android 视频画面拼接,Android实现视频剪切、视频拼接以及音视频合并
/*** mp4处理公共类* Created by lxy on 17-4-21.*/public classMp4ParseUtil {
/***对Mp4文件集合进行追加合并(按照顺序一个一个拼接起来)**@parammp4PathList[输入]Mp4文件路径的集合(支持m4a)(不支持wav)*@paramoutPutPath[输出]结果文件全部名称包含后缀(比如.mp4)*@throwsIOException格式不支持等情况抛出异常*/public static voidappendMp4List(List mp4PathList, String outPutPath){
try{
List mp4MovieList = newArrayList<>();// Movie对象集合[输入]for(String mp4Path : mp4PathList) {//将每个文件路径都构建成一个Movie对象mp4MovieList.add(MovieCreator.build(mp4Path));
}
List audioTracks = newLinkedList<>();//音频通道集合List videoTracks = newLinkedList<>();//视频通道集合for(Movie mp4Movie : mp4MovieList) {//对Movie对象集合进行循环for(Track inMovieTrack : mp4Movie.getTracks()) {
if("soun".equals(inMovieTrack.getHandler())) {//从Movie对象中取出音频通道audioTracks.add(inMovieTrack);
}
if("vide".equals(inMovieTrack.getHandler())) {//从Movie对象中取出视频通道videoTracks.add(inMovieTrack);
}
}
}
Movie resultMovie = newMovie();//结果Movie对象[输出]if(!audioTracks.isEmpty()) {//将所有音频通道追加合并resultMovie.addTrack(newAppendTrack(audioTracks.toArray(newTrack[audioTracks.size()])));
}
if(!videoTracks.isEmpty()) {//将所有视频通道追加合并resultMovie.addTrack(newAppendTrack(videoTracks.toArray(newTrack[videoTracks.size()])));
}
Container outContainer = newDefaultMp4Builder().build(resultMovie);//将结果Movie对象封装进容器FileChannel fileChannel = newRandomAccessFile(String.format(outPutPath), "rw").getChannel();
outContainer.writeContainer(fileChannel);//将容器内容写入磁盘fileChannel.close();
}catch(Exception e){
e.printStackTrace();
}
}
/***对AAC文件集合进行追加合并(按照顺序一个一个拼接起来)**@paramaacPathList[输入]AAC文件路径的集合(不支持wav)*@paramoutPutPath[输出]结果文件全部名称包含后缀(比如.aac)*@throwsIOException格式不支持等情况抛出异常*/public static voidappendAacList(List aacPathList, String outPutPath){
try{
List audioTracks = newLinkedList<>();//音频通道集合for(inti = 0; i < aacPathList.size(); i++) {//将每个文件路径都构建成一个AACTrackImpl对象audioTracks.add(newAACTrackImpl(newFileDataSourceImpl(aacPathList.get(i))));
}
Movie resultMovie = newMovie();//结果Movie对象[输出]if(!audioTracks.isEmpty()) {//将所有音频通道追加合并resultMovie.addTrack(newAppendTrack(audioTracks.toArray(newTrack[audioTracks.size()])));
}
Container outContainer = newDefaultMp4Builder().build(resultMovie);//将结果Movie对象封装进容器FileChannel fileChannel = newRandomAccessFile(String.format(outPutPath), "rw").getChannel();
outContainer.writeContainer(fileChannel);//将容器内容写入磁盘fileChannel.close();
}catch(Exception e){
e.printStackTrace();
}
}
private staticList moviesList= newArrayList<>();
private staticList videoTracks= newArrayList<>();
private staticList audioTracks= newArrayList<>();
//将两个mp4视频进行拼接public static voidappendMp4(List mMp4List,String outputpath){
try{
for(inti=0;i
Movie movie=MovieCreator.build(mMp4List.get(i));
moviesList.add(movie);
}
} catch(IOException e) {
e.printStackTrace();
}
for(Movie m : moviesList) {
for(Track t : m.getTracks()) {
if(t.getHandler().equals("soun")) {
audioTracks.add(t);
}
if(t.getHandler().equals("vide")) {
videoTracks.add(t);
}
}
}
Movie result = newMovie();
try{
if(audioTracks.size() > 0) {
result.addTrack(newAppendTrack(audioTracks.toArray(newTrack[audioTracks.size()])));
}
if(videoTracks.size() > 0) {
result.addTrack(newAppendTrack(videoTracks.toArray(newTrack[videoTracks.size()])));
}
} catch(IOException e) {
e.printStackTrace();
}
Container out = newDefaultMp4Builder().build(result);
try{
FileChannel fc = newFileOutputStream(newFile(outputpath)).getChannel();
out.writeContainer(fc);
fc.close();
} catch(Exception e) {
e.printStackTrace();
}
moviesList.clear();
}
/***将AAC和MP4进行混合[替换了视频的音轨]**@paramaacPath.aac*@parammp4Path.mp4*@paramoutPath.mp4*/public static booleanmuxAacMp4(String aacPath, String mp4Path, String outPath) {
booleanflag=false;
try{
AACTrackImpl aacTrack = newAACTrackImpl(newFileDataSourceImpl(aacPath));
Movie videoMovie = MovieCreator.build(mp4Path);
Track videoTracks = null;//获取视频的单纯视频部分for(Track videoMovieTrack : videoMovie.getTracks()) {
if("vide".equals(videoMovieTrack.getHandler())) {
videoTracks = videoMovieTrack;
}
}
Movie resultMovie = newMovie();
resultMovie.addTrack(videoTracks);//视频部分resultMovie.addTrack(aacTrack);//音频部分Container out = newDefaultMp4Builder().build(resultMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
flag=true;
Log.e("update_tag","merge finish");
} catch(Exception e) {
e.printStackTrace();
flag=false;
}
returnflag;
}
/***将M4A和MP4进行混合[替换了视频的音轨]**@paramm4aPath.m4a[同样可以使用.mp4]*@parammp4Path.mp4*@paramoutPath.mp4*/public static voidmuxM4AMp4(String m4aPath, String mp4Path, String outPath) throwsIOException {
Movie audioMovie = MovieCreator.build(m4aPath);
Track audioTracks = null;//获取视频的单纯音频部分for(Track audioMovieTrack : audioMovie.getTracks()) {
if("soun".equals(audioMovieTrack.getHandler())) {
audioTracks = audioMovieTrack;
}
}
Movie videoMovie = MovieCreator.build(mp4Path);
Track videoTracks = null;//获取视频的单纯视频部分for(Track videoMovieTrack : videoMovie.getTracks()) {
if("vide".equals(videoMovieTrack.getHandler())) {
videoTracks = videoMovieTrack;
}
}
Movie resultMovie = newMovie();
resultMovie.addTrack(videoTracks);//视频部分resultMovie.addTrack(audioTracks);//音频部分Container out = newDefaultMp4Builder().build(resultMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
}
/***分离mp4视频的音频部分,只保留视频部分**@parammp4Path.mp4*@paramoutPath.mp4*/public static voidsplitMp4(String mp4Path, String outPath){
try{
Movie videoMovie = MovieCreator.build(mp4Path);
Track videoTracks = null;//获取视频的单纯视频部分for(Track videoMovieTrack : videoMovie.getTracks()) {
if("vide".equals(videoMovieTrack.getHandler())) {
videoTracks = videoMovieTrack;
}
}
Movie resultMovie = newMovie();
resultMovie.addTrack(videoTracks);//视频部分Container out = newDefaultMp4Builder().build(resultMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
}catch(Exception e){
e.printStackTrace();
}
}
/***分离mp4的视频部分,只保留音频部分**@parammp4Path.mp4*@paramoutPath.aac*/public static voidsplitAac(String mp4Path, String outPath){
try{
Movie videoMovie = MovieCreator.build(mp4Path);
Track videoTracks = null;//获取音频的单纯视频部分for(Track videoMovieTrack : videoMovie.getTracks()) {
if("soun".equals(videoMovieTrack.getHandler())) {
videoTracks = videoMovieTrack;
}
}
Movie resultMovie = newMovie();
resultMovie.addTrack(videoTracks);//音频部分Container out = newDefaultMp4Builder().build(resultMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
}catch(Exception e){
e.printStackTrace();
}
}
/***分离mp4视频的音频部分,只保留视频部分**@parammp4Path.mp4*@parammp4OutPathmp4视频输出路径*@paramaacOutPathaac视频输出路径*/public static voidsplitVideo(String mp4Path, String mp4OutPath,String aacOutPath){
try{
Movie videoMovie = MovieCreator.build(mp4Path);
Track videTracks = null;//获取视频的单纯视频部分Track sounTracks = null;//获取视频的单纯音频部分for(Track videoMovieTrack : videoMovie.getTracks()) {
if("vide".equals(videoMovieTrack.getHandler())) {
videTracks = videoMovieTrack;
}
if("soun".equals(videoMovieTrack.getHandler())) {
sounTracks = videoMovieTrack;
}
}
Movie videMovie = newMovie();
videMovie.addTrack(videTracks);//视频部分Movie sounMovie = newMovie();
sounMovie.addTrack(sounTracks);//音频部分//视频部分Container videout = newDefaultMp4Builder().build(videMovie);
FileOutputStream videfos = newFileOutputStream(newFile(mp4OutPath));
videout.writeContainer(videfos.getChannel());
videfos.close();
//音频部分Container sounout = newDefaultMp4Builder().build(sounMovie);
FileOutputStream sounfos = newFileOutputStream(newFile(aacOutPath));
sounout.writeContainer(sounfos.getChannel());
sounfos.close();
}catch(Exception e){
e.printStackTrace();
}
}
/***对Mp4添加字幕**@parammp4Path.mp4添加字幕之前*@paramoutPath.mp4添加字幕之后*/public static voidaddSubtitles(String mp4Path, String outPath) throwsIOException {
Movie videoMovie = MovieCreator.build(mp4Path);
TextTrackImpl subTitleEng = newTextTrackImpl();//实例化文本通道对象subTitleEng.getTrackMetaData().setLanguage("eng");//设置元数据(语言)subTitleEng.getSubs().add(newTextTrackImpl.Line(0, 1000, "Five"));//参数时间毫秒值subTitleEng.getSubs().add(newTextTrackImpl.Line(1000, 2000, "Four"));
subTitleEng.getSubs().add(newTextTrackImpl.Line(2000, 3000, "Three"));
subTitleEng.getSubs().add(newTextTrackImpl.Line(3000, 4000, "Two"));
subTitleEng.getSubs().add(newTextTrackImpl.Line(4000, 5000, "one"));
subTitleEng.getSubs().add(newTextTrackImpl.Line(5001, 5002, " "));//省略去测试videoMovie.addTrack(subTitleEng);//将字幕通道添加进视频Movie对象中Container out = newDefaultMp4Builder().build(videoMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
}
/***将MP4切割**@parammp4Path.mp4*@paramfromSample起始位置 不是传入的秒数*@paramtoSample结束位置 不是传入的秒数*@paramoutPath.mp4*/public static voidcropMp4(String mp4Path, longfromSample, longtoSample, String outPath){
try{
Movie mp4Movie = MovieCreator.build(mp4Path);
Track videoTracks = null;//获取视频的单纯视频部分for(Track videoMovieTrack : mp4Movie.getTracks()) {
if("vide".equals(videoMovieTrack.getHandler())) {
videoTracks = videoMovieTrack;
}
}
Track audioTracks = null;//获取视频的单纯音频部分for(Track audioMovieTrack : mp4Movie.getTracks()) {
if("soun".equals(audioMovieTrack.getHandler())) {
audioTracks = audioMovieTrack;
}
}
Movie resultMovie = newMovie();
resultMovie.addTrack(newAppendTrack(newCroppedTrack(videoTracks, fromSample, toSample)));//视频部分resultMovie.addTrack(newAppendTrack(newCroppedTrack(audioTracks, fromSample, toSample)));//音频部分Container out = newDefaultMp4Builder().build(resultMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
android 视频画面拼接,Android实现视频剪切、视频拼接以及音视频合并相关推荐
- 一名合格的音视频开发人员,需要掌握哪些技能呢?音视频技术该怎么学?
在线教育.音视频会议.即时通讯等产品都是基于音视频技术开发,如今越来越多的App中都大量加入了音频.视频元素,比如说注册与登陆的扫脸验证,dou音.wei视的音视频变速.变调录制.实时滤镜.人脸识别特 ...
- 阿里云视频云低代码音视频工厂正式上线,以vPaaS全新定义企业级音视频应用开发
1月5日,阿里云视频云"低代码音视频工厂vPaaS"正式上线,极大程度降低音视频开发门槛,打破传统音视频技术壁垒,全新定义企业级的音视频应用开发. 低代码音视频工厂基于云原生.音视 ...
- android mp4 画面裁剪,Android视频时长裁剪
大家好,我是程序员kenney,今天给大家介绍一下如何在Android里面实现视频时长的裁剪. 首先我们要知道视频是由一帧一帧的数据构成的,每一帧都有一个时间戳,这个时间戳就是我们在做视频编码的时候, ...
- android编程:调节视频画面分辨率,Android编程实现屏幕自适应方向尺寸与分辨率的方法...
本文实例讲述了Android编程实现屏幕自适应方向尺寸与分辨率的方法.分享给大家供大家参考,具体如下: Android 屏幕自适应方向尺寸与分辨率,包括屏幕界面布局.多分辨率支持.获取屏幕尺寸.屏幕横 ...
- EasyPlayer:安卓播放器Android MediaMuxer录像(支持G711音频)支持MP4、音视频同步
Android平台的MediaMuxer是个非常好的录像库,它能将H.264视频+AAC音频存储成.mp4格式的文件,而且稳定性.同步效果都非常好.MediaMuxer在安卓版的EasyPlayer和 ...
- android 启动画面广告,Android 应用启动欢迎界面广告的实现实例
Android 应用启动欢迎界面广告 0.写在前面 在这篇教程中来实现一个类似于微信的的延迟3秒再进入主界面的效果. 1.项目准备 先新建一个空的android项目.里面只自带一个MainActivi ...
- 《音视频开发进阶指南》读书笔记(一) —— 音视频基础概念
前言 最近要学音视频,在图书馆借到这本<音视频开发进阶指南>,读了一段时间觉得挺好就在某宝买了. 以后一段时间应该都会沉浸在研究音视频中,开个专题记录哈每一章的读书笔记吧(以iOS开发的角 ...
- 音视频编解码流程与如何使用 FFMPEG 命令进行音视频处理
一.前言 FFMPEG 是特别强大的专门用于处理音视频的开源库.你既可以使用它的 API 对音视频进行处理,也可以使用它提供的工具,如 ffmpeg, ffplay, ffprobe,来编辑你的音视频 ...
- 视频编码h264怎么看_你所要知道的音视频--04
上一篇文章我们主要讲解了音频压缩算法的主要指标,以及几个典型的音频压缩算法.本章将延续上一讲的内容,分析视频压缩算法. 视频压缩算法 视频压缩算法比较,Wiki百科官方收录分类,请自备梯子 视频压缩算 ...
- 抖音短视频服务器维护中无法打开,打不开抖音视频的解决办法
打不开抖音视频的解决办法 2020-12-16 12:19:45 来源:网络整理 扫码可以: 1.在手机上浏览 2.分享给微信好友或朋友圈 摘要: 以抖音12.9.0版本为例,打不开抖音视频的原因及 ...
最新文章
- 生物界地震,AlphaFold破解50年重大挑战,AI+X将迎来新时代
- 深度剖析数据在内存中的存储1——数据类型
- Apache Camel入门
- java mapfile_基于文件的数据结构:关于MapFile
- P1092虫食算-深度优先搜索+玄学剪枝
- Spring Cloud核心组件原理分析
- 一步一步SharePoint 2007之二十二:完美解决实现Form认证后无法再用SharePoint Designer编辑网站的问题...
- final变量属性小记
- 大一java期末考笔试_JAVA考试试题及答案
- W型加密栅栏密码解密
- 信杂比公式_信噪比公式
- 深入理解JVM - 系统性能优化
- 超简单禁止迅雷下载!(分析+方法)
- 【OpenCV图像处理】五、图像的几何变换(下)
- 七、 标准型、基、基解、基可行解、可行基
- Wine Reviews(葡萄酒评论相关数据集)
- Java实现漏斗限流算法
- 【C语言】指针变量的定义、使用及初始化
- SQL 中的 NULL 原来是这么回事
- 基于单片机的步进电机开环控制系统
热门文章
- 将esx虚拟机从一台服务器迁移,vSphere实战攻略3:用VMotion迁移虚机
- word使用Bibtex4word插入参考文献
- 全新版的TFN 光时域反射仪上线了,大家一块了解一下吧。
- 【Python基础】3-语法进阶
- mysql 触发器delete_MySQL之触发器
- [源码解析] 深度学习流水线并行 PipeDream(3)--- 转换模型
- 带你白嫖程序带宽限制命令Trickle
- Win10系统还原文件默认打开方式
- scanf函数、冒泡排序和不定长度数组的使用 —— malloc
- python计算圆周率_python模拟蒙特·卡罗法计算圆周率