视频上传成功后需要对视频进行转码处理。
什么是视频编码?查阅百度百科如下:
详情参考 :百度百科-验证
首先我们要分清文件格式和编码格式:
文件格式:是指.mp4、.avi、.rmvb等 这些不同扩展名的视频文件的文件格式 ,视频文件的内容主要包括视频和音频,其文件格式是按照一 定的编码格式去编码,并且按照该文件所规定的封装格式将视频、音频、字幕等信息封装在一起,播放器会根据它们的封装格式去提取出编码,然后由播放器解码,最终播放音视频。
音视频编码格式:通过音视频的压缩技术,将视频格式转换成另一种视频格式,通过视频编码实现流媒体的传输。比如:一个.avi的视频文件原来的编码是a,通过编码后编码格式变为b,音频原来为c,通过编码后变为d。
音视频编码格式各类繁多,主要有几下几类:
(由ISO[国际标准组织机构]下属的MPEG[运动图象专家组]开发 )视频编码方面主要是Mpeg1(vcd用的就是它)、Mpeg2(DVD使用)、Mpeg4(的DVDRIP使用的都是它的变种,如:divx,xvid等)、Mpeg4 AVC(正热门);音频编码方面主要是MPEG Audio Layer 1/2、MPEG Audio Layer 3(大名鼎鼎的mp3)、MPEG-2 AAC 、MPEG-4 AAC等等。注意:DVD音频没有采用Mpeg的。
(由ITU[国际电传视讯联盟]主导,侧重网络传输,注意:只是视频编码)
包括H.261、H.262、H.263、H.263+、H.263++、H.264(就是MPEG4 AVC-合作的结晶)
目前最常用的编码标准是视频H.264,音频AAC。
提问:
H.264是编码格式还是文件格式?
mp4是编码格式还是文件格式?
我们将视频录制完成后,使用视频编码软件对视频进行编码,本项目 使用FFmpeg对视频进行编码 。
FFmpeg被许多开源项目采用,QQ影音、暴风影音、VLC等。
下载:FFmpeg Download FFmpeg
测试是否正常:cmd运行 ffmpeg -v
安装成功,作下简单测试
将一个.avi文件转成mp4、mp3、gif等。
比如我们将nacos.avi文件转成mp4,运行如下命令:
D:\soft\ffmpeg\ffmpeg.exe -i 1.avi 1.mp4
可以将ffmpeg.exe配置到环境变量path中,进入视频目录直接运行:ffmpeg.exe -i 1.avi 1.mp4
转成mp3:ffmpeg -i nacos.avi nacos.mp3
转成gif:ffmpeg -i nacos.avi nacos.gif
官方文档(英文):ffmpeg Documentation
将课程资料目录中的util.zip解压,将解压出的工具类拷贝至base工程。
其中Mp4VideoUtil类是用于将视频转为mp4格式,是我们项目要使用的工具类。
下边看下这个类的代码,并进行测试。
我们要通过ffmpeg对视频转码,Java程序调用ffmpeg,使用java.lang.ProcessBuilder去完成,具体在Mp4VideoUtil类的63行,下边进行简单的测试,下边的代码运行本机安装的QQ软件。
Java //启动QQ ProcessBuilder builder = new ProcessBuilder(); builder.command("D:\\QQ\\Bin\\QQScLauncher.exe"); //将标准输入流和错误输入流合并,通过标准输入流程读取信息 builder.redirectErrorStream(true); Process p = builder.start(); |
对Mp4VideoUtil类需要学习使用方法,下边代码将一个avi视频转为mp4视频,如下:
Java public static void main(String[] args) throws IOException { //转换文件 //ffmpeg的路径 String ffmpeg_path = "D:\\software\\ffmpeg\\ffmpeg.exe";//ffmpeg的安装位置 //源avi视频的路径 String video_path = "D:\\software\\Test\\xuecheng\\video\\11.avi"; //转换后mp4文件的名称 String mp4_name = "1.mp4"; //转换后mp4文件的路径 String mp4_path = "D:\\software\\Test\\xuecheng\\video\\1.mp4"; //创建工具类对象 Mp4VideoUtil videoUtil = new Mp4VideoUtil(ffmpeg_path, video_path, mp4_name, mp4_path); //开始视频转换,成功将返回success String s = videoUtil.generateMp4(); System.out.println(s); } |
执行main方法,最终在控制台输出 success 表示执行成功。
视频采用并发处理,每个视频使用一个线程去处理,每次处理的视频数量不要超过cpu核心数。
所有视频处理完成结束本次执行,为防止代码异常出现无限期等待则添加超时设置,到达超时时间还没有处理完成仍结束任务。
定义任务类VideoTask 如下:
Java package com.xuecheng.media.service.jobhander; import com.xuecheng.base.utils.Mp4VideoUtil; import com.xuecheng.media.model.po.MediaProcess; import com.xuecheng.media.service.MediaFileProcessService; import com.xuecheng.media.service.MediaFileService; import com.xxl.job.core.context.XxlJobHelper; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.File; import java.io.IOException; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * 视频采用并发处理,每个视频使用一个线程去处理,每次处理的视频数量不要超过cpu核心数。 * 所有视频处理完成结束本次执行,为防止代码异常出现无限期等待则添加超时设置,到达超时时间还没有处理完成仍结束任务。 */ @Component @Slf4j public class VideoTask { @Autowired MediaFileProcessService mediaFileProcessService; @Autowired MediaFileService mediaFileService; @Value("${videoprocess.ffmpegpath}") String ffmpegpath; /** * 视频处理任务 */ @XxlJob("videoJobHander") public void videoJobHander() throws Exception { // 分片参数 int shardIndex = XxlJobHelper.getShardIndex(); int shardTotal = XxlJobHelper.getShardTotal(); //查询待处理任务,一次处理的任务数要和cup核心一样 List |