首页 > 其他分享 >MediaExtractor+MediaMuxer分离/合成一个新的Mp4

MediaExtractor+MediaMuxer分离/合成一个新的Mp4

时间:2023-01-12 11:37:55浏览次数:50  
标签:MediaMuxer MediaExtractor mediaMuxer mediaExtractor Mp4 var bufferInfo 视频

一、概述

  案例:使用MediaExtractor和MediaMuxer生成一个新的无声的视频

二、代码示例

/**
 * 将Mp4文件中的视频单独提取出来,并重新生成一个无声的Mp4文件
 * ps:经过测试,是可以分离出无声的视频的,分离成功会弹出Toast
 */
class ExtractorMp4ToNoAudioActivity : BaseActivity() {
    override fun videoPathCallback(vidoPath: String?) {

    }

    private val VIDEO_SOURCE = "input.mp4"
    private val OUTPUT_VIDEO = "output.mp4"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_extractor_mp4_to_no_audio)
        copyFileToSdcard()
        btnExtractorNoAudioVideo.setOnClickListener {
            extractorNoAudioVideo()
        }

    }

    /**
     * 分离出没有音频的视频
     */
    @SuppressLint("WrongConstant")
    private fun extractorNoAudioVideo() {
        //创建媒体文件分离器
        var mediaExtractor = MediaExtractor()
        var mediaMuxer: MediaMuxer? = null
        try {
            //设置视频源
            val inputFile =
                File(Environment.getExternalStorageDirectory(), VIDEO_SOURCE)
            mediaExtractor.setDataSource(inputFile.absolutePath)
            //找到视频轨道索引
            var videoIndex = -1
            //视频轨道格式信息
            var videoFormat: MediaFormat? = null
            //找出视频轨道格式
            var trackCount = mediaExtractor.trackCount
            for (index in 0 until trackCount) {
                var mediaFormat = mediaExtractor.getTrackFormat(index)
                var mime = mediaFormat.getString(MediaFormat.KEY_MIME)
                if (mime.startsWith("video/")) {
                    videoIndex = index
                    videoFormat = mediaFormat
                    break;
                }
            }

            //切换想要的轨道
            mediaExtractor.selectTrack(videoIndex)

            //输入路径
            val outFile =
                File(Environment.getExternalStorageDirectory(), OUTPUT_VIDEO)
            if (outFile.exists()) {
                outFile.delete()
            }
            //实例化封装器,并置顶输出的媒体格式为mp4
            mediaMuxer =
                MediaMuxer(outFile.absolutePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
            //将视频轨添加到MediaMuxer,并返回新的轨
            var newTrackIndex = mediaMuxer.addTrack(videoFormat)
            var maxInputSize = videoFormat?.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)
            var byteBuffer = ByteBuffer.allocateDirect(maxInputSize!!)

            var bufferInfo = MediaCodec.BufferInfo()
            mediaMuxer.start()
            while (true) {
                //将样本数据存储到字节缓冲区
                var readSampleSize = mediaExtractor.readSampleData(byteBuffer, 0)
                //如果没有可获取的样本,退出循环
                if (readSampleSize < 0) {
                    mediaExtractor.unselectTrack(videoIndex)
                    break;
                }
                bufferInfo.size = readSampleSize
                bufferInfo.flags = mediaExtractor.sampleFlags
                bufferInfo.offset = 0
                bufferInfo.presentationTimeUs = mediaExtractor.sampleTime
                mediaMuxer.writeSampleData(newTrackIndex, byteBuffer, bufferInfo)
                //读取下一帧
                mediaExtractor.advance()
            }
            Toast.makeText(this, "分离视频完成", Toast.LENGTH_SHORT).show();

        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            //释放封装器和解封装器
            if (mediaMuxer != null) {
                mediaMuxer.stop()
                mediaMuxer.release()
            }
            mediaExtractor.release()

        }


    }

    /**
     * copy文件到sdcard
     */
    private fun copyFileToSdcard() {
        FileUtils.copyAssetsFileToSdcard(
            this@ExtractorMp4ToNoAudioActivity,
            VIDEO_SOURCE,
            object : FileUtils.OnCopySuccessListener {
                override fun onSuccess(inputPath: String?, outputPath: String?) {

                }

                override fun one rror(msg: String?) {

                }

            })
    }
}

 

标签:MediaMuxer,MediaExtractor,mediaMuxer,mediaExtractor,Mp4,var,bufferInfo,视频
From: https://www.cnblogs.com/tony-yang-flutter/p/17045966.html

相关文章

  • unknown directive "mp4" in /etc/nginx/nginx.conf
    unknowndirective"mp4"in/etc/nginx/nginx.conf 1、问题背景想通过nginx实现mp4格式视频的播放功能。在nginx配置文件(/etc/nginx/nginx.conf)中的配置如下:serve......
  • 免费MP4转换GIF工具开源
    实现效果开源原因:市面上的其他转换工具多半要收费,不划算,所以就开源了采用框架:PyQt5+moviepywin安装包地址:https://ytouch-1258011219.cos.ap-nanjing.myqcloud.com/dt_mp......
  • 音视频:JavaCV 视频转封装(flv转mp4)(不耗CPU)
    需要进行简单的音视频编程,如果不是特别数据C/C++,那么JavaCV应该是比较好的选择,下面记录一下使用JavaCV转封装(flv转mp4)(不耗CPU)的方法。转封装要比转码节省资源的多,速度也......
  • 音视频:JavaCV 视频转码(mkv转成mp4)(CPU)
    需要进行简单的音视频编程,如果不是特别数据C/C++,那么JavaCV应该是比较好的选择,下面记录一下JavaCV视频转码(非硬件加速)的方法。这里是将mkv转化成mp4,其他方式也是可以的......
  • vep文件转储mp4 文件提取器
    链接:https://pan.baidu.com/s/1dISmTcYeuOYBJajpWWaN1Q?pwd=b8ed提取码:b8ed将vep快速提取器.exe与HRC5.dll放到同一目录内运行vep快速提取器.exe点击选择文件,选择......
  • 【Azure 存储服务】MP4视频放在Azure的Blob里面,用生成URL在浏览器中打开之后,视频可以
    问题描述把MP4视频放在Azure的Blob里面,用生成URL在浏览器中打开之后,视频可以正常播放却无法拖拽视频的进度,这是什么情况呢? 问题解答因为MP4上传到AzureBlob后,根据公......
  • vue视频会议录屏并保存mp4格式到本地
    项目中,在视频会议中需要添加一个录屏功能主要是利用newMediaRecorder()来实现屏幕录制功能。//录制屏幕asyncscreenRecording(){//提示用户去选择和......
  • Qt音视频开发05-保存视频文件(yuv/h264/mp4)
    一、前言和音频存储类似,视频的存储也对应三种格式,视频最原始的数据是yuv(音频对应pcm),视频压缩后的数据是h264(音频对应aac),由于很多播放器或者早期的播放器不支持直接播放h26......
  • qnx环境下编译ffmpeg及解码mp4实践
    一ffmpeg简介1.ffmpeg是一套可以用来进行音视频处理的工具和编解码库;2.采用LGPL或GPL许可证(不能修改源码,只能使用so库,如果要修改源码,必须发布工程代码);3.ffmpeg对与硬件平台......
  • 【C#】使用ffmpeg image2pipe将图片保存为mp4视频
    文章目录需求实现需求在正式开始之前,先介绍下我的需求是怎么样的,基于此需求如何使用ffmpeg实现。仅供参考。需求点:将图片保存为视频图片数量不是固定的,是由上游的webrtc......