基于swing开发弹幕播放器

所属分类: 软件编程 / java 阅读数: 38
收藏 0 赞 0 分享

前言

跳过废话,直接看正文

近些年来,弹幕这种实时视频评论越来越火爆,国内几乎所有的视频网站在播放器中开始加入了弹幕的功能。弹幕已经成了很多人观看视频时不可缺少的一部分,我也是其中之一。

只是有时候因为网络问题、在线视频资源缺失等原因,人们通常会在本地观看离线视频,这时候要想看弹幕就有些麻烦了。经过搜索,我发现确实有一些软件能够实现在观看离线视频与弹幕的功能,比较出名的有BiliLocal以及DanDanPlayer这两个,在本质上,他们都是本地视频播放器,并通过在线搜索从各个弹幕网站下载弹幕资源并嵌入视频进行播放,都做的相当不错,只是在操作上有些麻烦,且都限制用户必须使用该播放器。

因此,我就用swing写了这个小工具,它不是视频播放器,而是专门用来播放弹幕文件的弹幕播放器,能够与视频播放器一起配合为用户提供离线观看视频以及弹幕的功能。

当然,这多少还是有重造车轮之嫌,毕竟嵌入弹幕的视频播放器也能够达到相同的效果,且集成的很好。只是对于程序员来说,用自己写的工具会更爽一些吧。这个东西写起来也就一两天的时间,就当做对swing编程的学习过程了。

正文

目录 

 •开发环境
 •软件架构
 •项目展示
 •一些问题

开发环境

 •操作系统:windows7
 •语言:Java
 •界面工具包:Swing
 •开发工具:IntellIj IDEA 2016.2.4
 •版本管理:git
 •运行环境:windows7、8、10 

软件架构

软件需要支持下面几种功能:

(1)根据url下载弹幕网站的弹幕文件
(2)加载离线弹幕文件并播放
(3)弹幕窗口置顶且背景透明
(4)基本的播放器控制功能(时间轴、暂停、播放)

我个人因为实习经历以及实验室项目的原因,参与开发了几个网站项目,因此对MVC框架比较熟悉,但是后来简单接触了下MVP模式,虽然是基于MVC的简单修改,但是个人觉得就代码解耦而言,MVP比MVC做得更好,因此就采用了MVP架构模式。当然,因为这是个小项目,为了节省时间,没有严格地按照MVP的架构来设计,(略去了Presenter 与View之间的接口层、减少了Presenter的数量等),但对此项目而言影响不大。

在此列出整个项目的文件结构图:

项目展示

弹幕控制器:

弹幕主窗口:

对此项目的源码感兴趣的朋友可以直接看我的git仓库

一些问题

我对swing还不太熟悉,因此在开发过程中遇到了一些问题,有些已经解决,有些还没有解决,现在列出一些比较关键的供大家参考:

 • 弹幕主窗口要实现背景透明但文字不透明的效果 

这个在windows下可以调用AWTUtilities中的相关函数实现,具体代码如下所示:

public class TransparentWindow extends JFrame {

public TransparentWindow(int width, int height) {
  this.setSize(width, height);
  this.setUndecorated(true);
  AWTUtilities.setWindowOpaque(this, false);
 }
}

但这个方法在windows中可以正常工作,在Linux中可能就不行了,具体是怎样的效果要看linux使用的图形桌面环境(GNOME下背景是透明的,但是文字飘过后会留下痕迹,重绘也不行。)

 • 爬取弹幕网站的弹幕文件 

因为没有统一的标准,每个网站的弹幕文件格式也不一样,需要自己定义一个格式,然后将不同来源的弹幕文件转换到这个格式即可

此外,在第一次写爬方法时,我发现下载下来的xml文件是乱码,后来才知道原来是经过deflate算法压缩的,需要进行解压缩,关键代码如下所示(使用apache的httpclient库获取HttpEntity):

private static HttpEntity decompressingEntityIfNecessary(HttpEntity entity)
{
 HttpEntity retEntity = entity;
 if (entity != null && entity.getContentEncoding() != null) {
  if ("gzip".equalsIgnoreCase(entity.getContentEncoding().getValue())) {
   retEntity = new GzipDecompressingEntity(entity);
  } else if ("deflate".equalsIgnoreCase(entity.getContentEncoding().getValue())) {
   retEntity = new DeflateDecompressingEntity(entity);
  }
 }
 return retEntity;
}

 • 时间轴控制 

这个还是第一次写,使用Timer来实现,遇到不少坑,最终效果还凑活。具体可以参考项目中的TimePanel.Java文件

 • 未解决的奔溃问题 

程序在windows10上正常运行,但在windows7下运行1分钟左右后会报APPCRASH

故障模块名称: ltc_game64-116096.dll
故障模块版本: 1.0.0.1
故障模块时间戳:    57cf505f
异常代码:   c000041d

具体原因不明,有了解的朋友希望能够指点一下,感激不尽。

后记

弹幕这种东西在将来或许能够规范化,成为一种与字幕类似的视频资源。这样每个视频都有对应的弹幕资源库,各种播放器也就能够从不同的弹幕资源库中加载并播放了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

Java concurrency之锁_动力节点Java学院整理

这篇文章主要为大家详细介绍了Java concurrency之锁的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java8新特性之StampedLock_动力节点Java学院整理

本文从synchronized、Lock到Java8新增的StampedLock进行对比分析,对Java8新特性之StampedLock相关知识感兴趣的朋友一起看看吧
收藏 0 赞 0 分享

Java8新特性之lambda的作用_动力节点Java学院整理

我们期待了很久lambda为java带来闭包的概念,但是如果我们不在集合中使用它的话,就损失了很大价值。现有接口迁移成为lambda风格的问题已经通过default methods解决了,在这篇文章将深入解析Java集合里面的批量数据操作解开lambda最强作用的神秘面纱。
收藏 0 赞 0 分享

Java8新特性之Base64详解_动力节点Java学院整理

这篇文章主要为大家详细介绍了Java8新特性之Base64的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java8新特性之JavaFX 8_动力节点Java学院整理

这篇文章主要介绍了Java8新特性之JavaFX 8的相关知识,非常不错,具有参考借鉴价值,需要的朋友参考下吧
收藏 0 赞 0 分享

将本地jar包安装进入maven仓库(实现方法)

下面小编就为大家带来一篇将本地jar包安装进入maven仓库(实现方法)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

浅谈Java finally语句到底是在return之前还是之后执行(必看篇)

下面小编就为大家带来一篇浅谈Java finally语句到底是在return之前还是之后执行(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

基于Java并发容器ConcurrentHashMap#put方法解析

下面小编就为大家带来一篇基于Java并发容器ConcurrentHashMap#put方法解析。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详解Spring Boot Profiles 配置和使用

本篇文章主要介绍了详解Spring Boot Profiles 配置和使用,具有一定的参考价值,有兴趣的可以了解一下
收藏 0 赞 0 分享

详解Spring Boot 属性配置和使用

本篇文章主要介绍了详解Spring Boot 属性配置和使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多