android.MediaMuxer时间裁剪

使用MediaMuxer裁剪视频_安卓muxer 裁剪视频画布-CSDN博客

关键步骤

mediaExtractor.seekTo(beginTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);long presentTimeUs = mediaExtractor.getSampleTime();
if (presentTimeUs > endTime)break;

功能代码

VideoView videoView_video;
ImageButton imageButton_startTime, imageButton_endTime;
Button button_clip;
String path_video="";
int startTime, endTime;imageButton_startTime = (ImageButton)findViewById(R.id.imageButton_startTime);
imageButton_startTime.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {startTime = videoView_video.getCurrentPosition(); //msToast.makeText(getApplicationContext(), "开始时间:" + startTime, Toast.LENGTH_SHORT).show();}
});imageButton_endTime = (ImageButton)findViewById(R.id.imageButton_endTime);
imageButton_endTime.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {endTime = videoView_video.getCurrentPosition();Toast.makeText(getApplicationContext(), "结束时间:" + endTime, Toast.LENGTH_SHORT).show();}
});button_clip = (Button)findViewById(R.id.button_clip);
button_clip.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (path_video.equals("")) {Toast.makeText(getApplicationContext(), "错误:没有视频", Toast.LENGTH_SHORT).show();return;}if (startTime >= endTime) {Toast.makeText(getApplicationContext(), "错误:开始时间(" + startTime + ") > 结束时间(" + endTime + ")", Toast.LENGTH_SHORT).show();return;}String path_output = Environment.getExternalStorageDirectory().getPath() + File.separator + Environment.DIRECTORY_MOVIES + path_video.substring(path_video.lastIndexOf("/"), path_video.lastIndexOf(".")) + "_clip.mp4";clipVideo(path_video, path_output, startTime, endTime);}
});

 

void clipVideo(String path_video, String path_output, int startTime, int endTime) {MediaExtractor mediaExtractor = new MediaExtractor();try {mediaExtractor.setDataSource(path_video);} catch (Exception e) {Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());}int videoTrack = -1,audioTrack = -1;if (mediaExtractor.getTrackCount() == 0) {Toast.makeText(getApplicationContext(), "错误:trackCount == 0", Toast.LENGTH_SHORT).show();return;}for (int i = 0; i < mediaExtractor.getTrackCount(); i++) {if (mediaExtractor.getTrackFormat(i).getString(MediaFormat.KEY_MIME).startsWith("video/")) {videoTrack = i;} else if (mediaExtractor.getTrackFormat(i).getString(MediaFormat.KEY_MIME).startsWith("audio/")) {audioTrack = i;}}Toast.makeText(getApplicationContext(), "videoTrack: " + videoTrack + "\naudioTrack: " + audioTrack, Toast.LENGTH_SHORT).show();Log.e(Thread.currentThread().getStackTrace()[2] + "", "videoTrack: " + videoTrack + ", audioTrack: " + audioTrack);MediaFormat videoFormat = mediaExtractor.getTrackFormat(videoTrack);MediaFormat audioFormat = mediaExtractor.getTrackFormat(audioTrack);MediaMuxer mediaMuxer = null;try {mediaMuxer = new MediaMuxer(path_output, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);} catch (Exception e) {Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();Log.e(Thread.currentThread().getStackTrace()[2] + "", e.toString());}int videoTrackIndex = mediaMuxer.addTrack(videoFormat);//int rotation = videoFormat.getInteger(MediaFormat.KEY_ROTATION); //视频的rotation//mediaMuxer.setOrientationHint(rotation);int audioTrackIndex = mediaMuxer.addTrack(audioFormat);mediaMuxer.start();int bufferSize = 256 * 1024;ByteBuffer inputBuffer = ByteBuffer.allocate(bufferSize);//视频部分mediaExtractor.selectTrack(videoTrack);MediaCodec.BufferInfo videoInfo = new MediaCodec.BufferInfo();mediaExtractor.seekTo(startTime * 1000L, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);while (true) {int sampleSize = mediaExtractor.readSampleData(inputBuffer, 0);long presentationTimeUs = mediaExtractor.getSampleTime();if (sampleSize < 0 || presentationTimeUs > endTime * 1000L) {mediaExtractor.unselectTrack(videoTrack);break;}//int trackIndex = mediaExtractor.getSampleTrackIndex();int sampleFlag = mediaExtractor.getSampleFlags();videoInfo.offset = 0;videoInfo.size = sampleSize;videoInfo.flags = sampleFlag;videoInfo.presentationTimeUs = presentationTimeUs;mediaMuxer.writeSampleData(videoTrackIndex, inputBuffer, videoInfo);mediaExtractor.advance();}//音频mediaExtractor.selectTrack(audioTrack);MediaCodec.BufferInfo audioInfo = new MediaCodec.BufferInfo();mediaExtractor.seekTo(startTime * 1000L, MediaExtractor.SEEK_TO_CLOSEST_SYNC);while (true) {int sampleSize = mediaExtractor.readSampleData(inputBuffer, 0);long presentationTimeUs = mediaExtractor.getSampleTime();if (sampleSize < 0 || presentationTimeUs > endTime * 1000L) {mediaExtractor.unselectTrack(audioTrack);break;}//int trackIndex = mediaExtractor.getSampleTrackIndex();int sampleFlag = mediaExtractor.getSampleFlags();audioInfo.offset = 0;audioInfo.size = sampleSize;audioInfo.flags = sampleFlag;audioInfo.presentationTimeUs = presentationTimeUs;mediaMuxer.writeSampleData(audioTrackIndex, inputBuffer, audioInfo);mediaExtractor.advance();}mediaMuxer.stop();mediaMuxer.release();mediaExtractor.release();MediaScannerConnection.scanFile(getApplicationContext(), new String[]{path_output}, null, null);Toast.makeText(getApplicationContext(), "视频剪辑完成:" + path_output, Toast.LENGTH_SHORT).show();
}

源码:GitLink | 确实开源

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/663685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【每日一题】石子游戏 VI

文章目录 Tag题目来源解题思路方法一&#xff1a;贪心排序 写在最后 Tag 【贪心排序】【数组】【2024-02-02】 题目来源 1686. 石子游戏 VI 解题思路 方法一&#xff1a;贪心排序 思路 假设有两个石子 i 和 j&#xff0c;Alice 和 Bob 认为它们的价值分别为 a i a_i ai​…

Linux系统Shell脚本-----------正则表达式 文本三剑客之---------grep、 sed

一、正则表达式 1.前言 正则表达式(regular expression)描述了一种字符串匹配的模式&#xff08;pattern&#xff09;&#xff0c;可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。在Linux中也就是代表我们定义的模式模板&…

qt学习:qt项目移植多平台

目录 window linux 安装qt步骤 在linux编译可执行程序步骤 arm 要先移植交叉编译链才能在ubuntu里生成arm的qt可执行文件&#xff0c;下面是步骤 安装arm的qmake 在linux编译可执行程序步骤 进入官网下载qt&#xff0c;下载window&#xff0c;linux的安装包&#xff0c…

localstorage de yongfa

1. **设置一个项目** javascript localStorage.setItem("myCat", "Whiskers"); 2. **获取一个项目** javascript let myCat localStorage.getItem("myCat"); 3. **删除一个项目** javascript localStorage.removeItem(…

让Unity迭代器性能提升5倍

最近在研究Unity il2cpp的代码生成和编译优化&#xff0c;结合之前遇到过的一个优化案例&#xff0c;给大家讲讲在Unity中迭代器相关代码生成的底层原理&#xff0c;以及在写代码过程中需要注意的一些特殊情况。 案例 首先我们来看一个非常简单的案例&#xff0c;代码如下&am…

Linux实验记录:使用Apache服务部署静态网站

前言&#xff1a; 本文是一篇关于Linux系统初学者的实验记录。 参考书籍&#xff1a;《Linux就该这么学》 实验环境&#xff1a; VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 目录 前言&#xff1a; 备注&#xff1a; 正文&…

【C语言进阶篇】assert宏 使用详解

文章目录 一、assert简介 二、assert使用方法和规则 2.1 头文件 2.2 原型 2.3 功能 2.4 示例 2.5 assert的打开与关闭 三、注意事项 3.1 运行效率问题 3.2 assert只适用于调试版本 3.3 资源释放与清理 3.4 过度依赖 四、总结 个人主页&#xff1a; 倔强的石头的…

API横向越权修复之ID加密

横向越权 横向越权一般发生在应用系统做了【认证】&#xff0c;但没有做【鉴权】的情况下&#xff0c;也是最常见的漏洞之一。 认证&#xff1a;即识别是否有权限访问系统&#xff1b;鉴权&#xff1a;即识别在系统中的权限是什么&#xff1b; 例如&#xff1a; // 访问某…

氢气传感器报警值:守护实验室安全的隐形卫士

随着科技的发展&#xff0c;我们的生活变得越来越便捷&#xff0c;但是与此同时&#xff0c;安全问题也日益凸显。其中&#xff0c;氢气作为一种清洁能源&#xff0c;被广泛应用于各个领域&#xff0c;但是如果不加以控制&#xff0c;氢气泄漏也可能带来严重的安全隐患。因此&a…

柔性电流探头方向判断有哪些方法?干货分享!

柔性电流探头方向判断的方法干货分享&#xff01;从理论到实践&#xff0c;助您成为专业人士&#xff01;干货收藏&#xff0c;快看起来吧&#xff01;      柔性电流探头方向判断一直是电力行业测试中的关键问题之一&#xff0c;确切地判断电流方向对于测试电力系统的稳定…

Docker部署xxl-job调度器并结合SpringBoot测试

文章目录 一、Docker部署1. 创建数据库2. 启动容器3. 访问4. 新建执行器 二、SpringBoot整合1. 模块注册到执行器2. 创建配置类3. 启动测试 三、任务发布-普通任务1. 编写任务代码2. 创建任务3. 启动任务 四、任务发布-分片任务1. 编写任务代码2. 启动多个实例3. 创建任务4. 启…

MYSQL Case When搜索查询

Case When可以用作select语句中的搜索&#xff0c;如果满足条件&#xff0c;就给字段附上结果值。 语法&#xff1a; CASE WHEN 表达式1 THEN 结果1 WHEN 表达式2 THEN 结果2WHEN 表达式3 THEN 结果3ELSE 其他结果 END简单的例子&#xff1a; 当学生表tb_student里&#xff…

CTF特训(二):青少年CTF-MISC部分WP

FLAG&#xff1a;当觉得自己很菜的时候&#xff0c;就静下心来学习 专研方向:MISC&#xff0c;CTF 每日emo&#xff1a;听一千遍反方向的钟&#xff0c;我们能回到过去吗&#xff1f; CTF特训(二)&#xff1a;青少年CTF-MISC部分WP&#xff1a; 文章目录 CTF特训(二)&#xff1…

IDEA开发使用 thymeleaf 模板$表达式报红波浪线解决方案

系列文章目录 文章目录 系列文章目录后端存值前端取值thymeleaf 后端存值 RequestMapping("/testModelAndView")//使用ModelAndView时返回的方法类型必须是ModelAndViewpublic ModelAndView testModelAndView() {//创建ModelAndView对象ModelAndView mav new Model…

QT播放gstreamer命令(三)---使用QMediaPlayer

前文&#xff1a; 因为之前听说过&#xff0c;QMediaPlayer已经集成了gstreamer&#xff0c;但是并没有什么接口来例子来说明&#xff0c;根本看不出来有任何gstreamer的形式&#xff0c;于是在QT5助手里面搜了一下&#xff0c;发现确实有gstreamer的痕迹&#xff0c;但是例子写…

vue中template原理

在Vue中&#xff0c;template具有非常重要的作用&#xff0c;它能将数据渲染到用户界面上&#xff0c;达到我们所预想的效果。Vue的template是基于类似于html的语法&#xff0c;但是它还有一些独特的规则。在Vue中&#xff0c;template语法会被转换成虚拟DOM&#xff0c;在和Vu…

谷歌浏览器网站打不开,显示叹号

问题&#xff1a; 您与此网站之间建立的连接不安全请勿在此网站上输入任何敏感信息&#xff08;例如密码或信用卡信息&#xff09;&#xff0c;因为攻击者可能会盗取这些信息。 了解详情 解决方式&#xff1a; 网上有很多原因&#xff0c;亲测为DNS问题&#xff0c;设置&…

Qt之窗口位置

Qt提供了很多关于获取窗体位置及显示区域大小的函数&#xff0c;如x&#xff08;&#xff09;&#xff0c;y()和pos()&#xff0c;rect()&#xff0c;size()&#xff0c;geometry()等&#xff0c;统称为"位置相关函数"或"位置函数"。几种主要位置函数及其之…

82.1W/S的QPS到底大不大?

QPS&#xff0c;全称是Query Per Second&#xff0c;即每秒查询次数。它是一种衡量系统处理能力的重要指标。"每秒1万"的QPS对于一般的个人网站或者中小型网站来说&#xff0c;是相当高的。但是对于大型网站、互联网公司或高并发系统来说&#xff0c;可能就略显不足。…

第0章 Linux 基础入门

第0章 Linux 基础入门 RHCSA Red Hat Certified System Administrator 红帽认证系统管理员。 什么是计算机 计算机的组成&#xff1a; 控制器 运算器 存储器 输出设备 输入设备 计算机只能识别0和1&#xff0c;也就是二进制数。 为什么要学习Linux Linux 因其高效率…