Java实现视频处理和播放的详细教程
我们知道,现在视频可以说是最火爆的多媒体手段了,所以顺带着视频处理技术也就成了目前炙手可热的技术之一了。我们作为一个Java程序员,又该怎么处理视频呢?今天Java架构栈就给大家讲解一下,如何通过Java代码来实现视频处理及播放。
一. 需要了解的技术点
在具体实现之前,我们先来看看视频处理需要了解的技术点都有哪些。
FFmpeg
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。 FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。 [1] FFmpeg编码库可以使用GPU加速。
HLS
HLS(HTTP Live Streaming)是Apple的动态码率自适应技术。主要用于PC和Apple终端的音视频服务。包括一个m3u8的索引文件,TS媒体分片文件和key加密串文件。
HLS的工作原理:将视频文件分成多个ts格式的小文件,通过m3u8格式的索引文件对这些ts小文件组织索引。播放器可以通过连接m3u8文件播放视频,当要快进时可以通过m3u8这个索引文件找到对应的小文件,并去下载对应的ts文件,最终可以实现快进、快退、实时播放等功能。
m3u8所以文件和ts小文件可以让FFmpeg帮我们生成。
video.js 网络播放器
Video.js是一个为HTML5世界从头开始构建的网络视频播放器。它支持HTML5视频和现代流媒体格式,它支持桌面和移动设备上的视频播放。该项目于2010年中期启动,目前已有数百名撰稿人,在450000多个网站上使用。
官方地址:https://videojs.com/
二. 具体实现步骤
了解完上面的这些基本理论知识后,接下来咱们就来看看该如何进行代码实现吧。
使用ffmpeg将录制的avi格式文件生成MP4文件
我们可以把avi格式的文件转为mp4格式的文件,实现代码如下所示:
/**
生成avi文件生成mp4文件
@param ffmpeg_path ffmpeg的安装路径:C:\Program Files\ffmpeg-master-latest-win64-gpl-shared\bin\ffmpeg.exe
@param video_path 要转化的avi文件地址
@param mp4folder_path 生成的MP4存放路径
@param mp4_name 生成的MP4文件名
@return 成功返回ok,失败返回error
*/
public String makeMp4(String ffmpeg_path,String video_path,String mp4folder_path,String mp4_name){
//ffmpeg.exe -i qfedu.avi -c:v libx264 -s 1280x720 -pix_fmt yuv420p -b:a 63k -b:v 753k -r 18 .\qfedu.mp4
// 通过 ProcessBuilder 执行 ffmpeg.exe
List cmd = new ArrayList();
cmd.add(ffmpeg_path);
cmd.add("-i");
cmd.add(video_path);
cmd.add("-c:v");
cmd.add("libx264");
cmd.add("-y");
cmd.add("-s");
cmd.add("1280x720");
cmd.add("-pix_fmt");
cmd.add("yuv420p");
cmd.add("-b:a");
cmd.add("63k");
cmd.add("-b:v");
cmd.add("753k");
cmd.add("-r");
cmd.add("18");
cmd.add(mp4folder_path + mp4_name );
String outstring = null;
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(cmd);
builder.redirectErrorStream(true);
Process process = builder.start();
outstring = getProcessResult(process);
System.out.println(outstring);
return "ok";
} catch (Exception ex) {
ex.printStackTrace();
return "error";
}
}
/**
获取进程执行结果
*/
public String getProcessResult(Process process) {
String result = "error";
int exitValue = -1;
InputStream inputStream = null;
InputStream errorInputStream = null;
StringBuffer outputString = new StringBuffer();
try {
inputStream = process.getInputStream();
errorInputStream = process.getErrorStream();
boolean finished = false;
int max = 300;//每次休眠1秒,最长执行时间5分种
int count = 0;
while (!finished) {
//超过5分钟,默认失败
if (retry > max) {
return "error";
}
try {
while (inputStream.available() > 0) {
Character c = new Character((char) inputStream.read());
outputString.append(c);
System.out.print(c);
}
while (errorInputStream.available() > 0) {
Character c = new Character((char) errorInputStream.read());
outputString.append(c);
System.out.print(c);
}
exitValue = p.exitValue();
finished = true;
} catch (IllegalThreadStateException e) {
Thread.currentThread().sleep(1000);//休眠1秒
count++;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
return outputString.toString();
使用ffmpeg将MP4文件生成m3u8/ts文件
我们也可以把MP4格式的文件转换为m3u8/ts格式的文件,实现代码如下所示:
/**
生成m3u8文件
@param ffmpeg_path ffmpeg的安装路径:C:\Program Files\ffmpeg-master-latest-win64-gpl-shared\bin\ffmpeg.exe
@param video_path 要转化的mp4文件地址
@param m3u8folder_path 生成m3u8的存放路径
@param m3u8_name 生成的m3u8文件名
@return 成功返回ok,失败返回error
@return 成功则返回success,失败error
/
public String makeM3u8(String ffmpeg_path,String video_path,String m3u8folder_path,String m3u8_name) {
/
ffmpeg -i qfedu.mp4 -hls_time 10 -hls_list_size 0 -hls_segment_filename ./hls/qfedu_%05d.ts ./hls/qfedu.m3u8
*/
List cmd = new ArrayList();
cmd.add(ffmpeg_path);
cmd.add("-i");
cmd.add(video_path);
cmd.add("-hls_time");
cmd.add("10");
cmd.add("-hls_list_size");
cmd.add("0");
cmd.add("-hls_segment_filename");
cmd.add(m3u8folder_path + m3u8_name.substring(0, m3u8_name.lastIndexOf(".")) + "_%05d.ts");
cmd.add(m3u8folder_path + m3u8_name);
String out = null;
try {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(cmd);
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
out = getProcessResult(process);
System.out.println(out);
} catch (Exception e) {
e.printStackTrace();
}
//通过检查生成的m3u8的文件列表判断是否成功
List tsList = getTsList(m3u8folder_path,m3u8_name);
if (tsList == null) {
return "error";
}
return "success";
}
/**
获取ts列表
@return ts列表
*/
public List getTsList(String m3u8folder_path,String m3u8_name ) {
List fileList = new ArrayList();
List tsList = new ArrayList();
String m3u8file_path = m3u8folder_path + m3u8_name;
BufferedReader reader = null;
String str = null;
String line = "";
try {
reader = new BufferedReader(new FileReader(m3u8file_path));
while ((str = reader.readLine()) != null) {
line = str;
if (line.endsWith(".ts")) {
tsList.add(line);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if (line.contains("#EXT-X-ENDLIST")) {
fileList.addAll(tsList);
return fileList;
}
return null;
}
使用基于html5支持Video.js网络视频播放器播放视频
我们也可以在html页面中,把处理好的视频嵌入进来,供用户流量播放。
推荐阅读
-
Java 8新特性探究(十三)JavaFX 8新特性以及开发2048游戏-JavaFX历史## 跟java在服务器端和web端成绩相比,桌面一直是java的软肋,于是Sun公司在2008年推出JavaFX,弥补桌面软件的缺陷,请看下图JavaFX一路走过来的改进 从上图看出,一开始推出时候,开发者需使用一种名为JavaFX Script的静态的、声明式的编程语言来开发JavaFX应用程序。因为JavaFX Script将会被编译为Java bytecode,程序员可以使用Java代码代替。 JavaFX 2.0之后的版本摒弃了JavaFX Script语言,而作为一个Java API来使用。因此使用JavaFX平台实现的应用程序将直接通过标准Java代码来实现。 JavaFX 2.0 包含非常丰富的 UI 控件、图形和多媒体特性用于简化可视化应用的开发,WebView可直接在应用中嵌入网页;另外 2.0 版本允许使用 FXML 进行 UI 定义,这是一个脚本化基于 XML 的标识语言。 从JDK 7u6开始,JavaFx就与JDK捆绑在一起了,JavaFX团队称,下一个版本将是8.0,目前所有的工作都已经围绕8.0库进行。这是因为JavaFX将捆绑在Java 8中,因此该团队决定跳过几个版本号,迎头赶上Java 8。 ##JavaFx8的新特性 ## ###全新现代主题:Modena 新的Modena主题来替换原来的Caspian主题。不过在Application的start方法中,可以通过setUserAgentStylesheet(STYLESHEET_CASPIAN)来继续使用Caspian主题。 参考http://fxexperience.com/2013/03/modena-theme-update/ ###JavaFX 3D 在JavaFX8中提供了3D图像处理API,包括Shape3D (Box, Cylinder, MeshView, Sphere子类),SubScene, Material, PickResult, LightBase (AmbientLight 和PointLight子类),SceneAntialiasing等。Camera类也得到了更新。从JavaDoc中可以找到更多信息。 ###富文本 强化了富文本的支持 ###TreeTableView ###日期控件DatePicker 增加日期控件 ###用于 CSS 结构的公共 API
-
下载和播放缓存视频同时进行:一种实现iOS音频和视频播放器的方法
-
"设计与实现基于SpringBoot的校园失物招领网站/平台/系统的计算机毕业设计:Java实战项目附带源码,文档和视频讲解"
-
打造你的专属微信!跟着教程一步一步制作私信和群聊 Android App(附带源码和演示视频,超详细讲解)
-
简易教程:在Java中搭建Red5服务器进行实时直播和流媒体视频播放
-
Java工具类:轻松处理视频上传、转换、播放和下载的多格式支持
-
用Java和JAVACV制作带音乐的短视频——图像合成教程
-
Java实现视频处理和播放的详细教程
-
Java实现视频上传和播放功能教程
-
用Java实现在线视频播放的方法