Kotlinのコードサンプルは、この記事の構文を使用しますが、ない高度な機能
MediaExtractor:分離できるビデオファイル、ビデオとオーディオを抽出
MediaMuxerを、シンセサイザーのオーディオおよびビデオファイルのビデオとオーディオの合成新しいビデオ抽出することができます:
MediaFormatを:抽出取得したメディア・フォーマット・クラス、取得を保存メディア情報(メディアタイプ、
フレームレート、等)
1.設定権限が必要
。それがローカルファイルである場合は、読み取りと書き込みを伴います、あなたがマニフェストを設定する必要があります
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
6.0はここでは省略し、動的なコードのために適用するには
2.ビデオファイルを入手し必要
この論文は、ContentResolverのを介して直接マルチメディアファイルを照会することです
val cursor = contentResolver.query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
null, null, null, null
)
查询到的数据存储到了自建的Song类中,存了文件名(name)和路径(path),然后用ListView展示,
次のファイルおよび使用に直接隣接する時間を、保存するには、ビデオとオーディオを抽出するための原料として、ファイルをクリックされ
ますが、ファイルを探すために気にしない場合は動画ファイルも直接のres /生フォルダに入れることができ、生独自に作成
その後、ファイルを取得し、MediaExtractor.setDataSourceは埋めるために多くの方法をサポート
3.抽出オーディオとビデオ
/**
* 配置音视频提取器
* @param position 点击的文件下标
*/
fun configureVideoAndAudioExtractor(position: Int) {
try {
//1.设置要提取视频的文件
//
/**
*
* MediaExtractor反复提示初始化失败
* 1.检查文件访问权限
* 2.检查视频文件大小是否大于0!!!!!!!!!!!!!!!
*3.最好不要用拼接路径,比如
* mVideoMediaExtractor.setDataSource(context.getFilesDir()+"xxx.mp4")
* 最好添加路径变量或完整路径地址,比如下面的变量或
* "mnt/sdcard/.../.../xxx.mp4"这种的
*/
//初始化解析器和合成器对象,合成输入的格式是mp4,
//outputVideoPath是合成后输出的路径,自己构建就好
//我的是fileDir+“video.mp4”
mMediaMuxer = MediaMuxer(outputVideoPath,
MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
mVideoMediaExtractor = MediaExtractor()
mAudioMediaExtractor = MediaExtractor()
//songList是一个集合,存着Song类,
//设置要提取出视频的原材料文件
mVideoMediaExtractor.setDataSource(songList[position].path)
//设置要提取出音频的文件
mAudioMediaExtractor.setDataSource(songList[position].path)
//获取轨道,找到视频轨道
for (i in 0 until mVideoMediaExtractor.trackCount) {
val mediaFormat = mVideoMediaExtractor.getTrackFormat(i)
if (mediaFormat.getString(MediaFormat.KEY_MIME).startsWith("video/")) {
//获取到视频轨道
mVideoMediaExtractor.selectTrack(i)
//获取添加到Muxer后生成的新的视频轨道下标
videoMuxerTrackIndex = mMediaMuxer.addTrack(mediaFormat)
//获取视频帧最大值,为了后面合成新视频,读取文件时候设定缓冲区大小
maxFrameSize = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)
//获取视频帧率,为了后面计算获取到的文件处于的播放时间
frameRate = mediaFormat.getInteger(MediaFormat.KEY_FRAME_RATE)
}
}
//找到视频文件中的音频轨道,方法和获取视频差不多
for (j in 0 until mAudioMediaExtractor.trackCount) {
val mediaFormat = mAudioMediaExtractor.getTrackFormat(j)
if (mediaFormat.getString(MediaFormat.KEY_MIME).startsWith("audio/")) {
//获取音轨
mAudioMediaExtractor.selectTrack(j)
//添加音轨到Muxer
audioMuxerTrackIndex = mMediaMuxer.addTrack(mediaFormat)
//获取音频最大输入,为了计算缓冲区大小
maxAudioSize = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)
}
}
//这个方法内执行MediaMuxer的合成操作,下面会贴出来
compoundVideoAndAudioWithPermissionCheck()
} catch (e: IOException) {
Log.i("exception", e.message)
} finally {
//释放资源,切记最后要是放资源,重新添加合成文件时候要新建MediaExtractor和MediaMuxer
if (mMediaMuxer != null) {
mMediaMuxer.release()
}
if (mVideoMediaExtractor != null) {
mVideoMediaExtractor.release()
}
if (mAudioMediaExtractor != null) {
mAudioMediaExtractor.release()
}
}
}
ステップは、要約することです
MediaExtractorとMediaMuxerは、オブジェクトの作成1.
)2. MediaExtractorオブジェクト(のファイルsetDataSourceの必要性を追加
)(3.forビデオトラックを取得するためのサイクルとオーディオトラックMediaExtractor#selectTrack、とにMediaMuxerに追加
(MediaMuxer#addTrack)
4マージを開始
オーディオとビデオの4合成
/**
* 合成视频和音频
*/
fun compoundVideoAndAudio() {
//1.开始合成
mMediaMuxer.start()
//2.输入提取到的视频,videoMuxerTrackIndex是之前addTrack生成的下标,
//如果为-1就是添加失败
if (-1 != videoMuxerTrackIndex) {
//描述缓冲区数据信息类,最后Muxer合成要求有的东西
val videoBufferInfo = MediaCodec.BufferInfo()
//创建缓冲区,最后Muxer合成要求有的东西
val videoByteBuffer = ByteBuffer.allocate(maxFrameSize)
while (true) {
/3./获取样本大小
val videoSampleSize = mVideoMediaExtractor.readSampleData(videoByteBuffer, 0)
if (videoSampleSize < 0) {
break
}
//4.设置样本信息
videoBufferInfo.offset = 0 //堆buffer缓冲区写入时的字节偏移
videoBufferInfo.size = videoSampleSize
videoBufferInfo.flags = mVideoMediaExtractor.sampleFlags
//读取到的文件的时间戳,单位是微秒
videoBufferInfo.presentationTimeUs += 1000 * 1000 / frameRate //每次加每帧的微秒数
//MediaMuxer写入样本数据
//videoMuxerTrackIndex 之前加入Muxer的视频轨下标
//videoByteBuffer 上面创建的Buffer对象
//videoBufferInfo 上面创建的BufferInfo对象
mMediaMuxer.writeSampleData(videoMuxerTrackIndex, videoByteBuffer, videoBufferInfo)
//5.推进到下个样本 类似快进
mVideoMediaExtractor.advance()
}
}
/**
* 合成音频,和视频类似
*/
if (-1 != audioMuxerTrackIndex) {
val audioBufferInfo = MediaCodec.BufferInfo()
val audioByteBuffer = ByteBuffer.allocate(maxAudioSize)
while (true) {
val audioSampleSize = mAudioMediaExtractor.readSampleData(audioByteBuffer, 0)
if (audioSampleSize < 0) {
break
}
audioBufferInfo.offset = 0
audioBufferInfo.size = audioSampleSize
audioBufferInfo.flags = mAudioMediaExtractor.sampleFlags
audioBufferInfo.presentationTimeUs += 1000 * 1000 / frameRate
mMediaMuxer.writeSampleData(audioMuxerTrackIndex, audioByteBuffer, audioBufferInfo)
mAudioMediaExtractor.advance()
}
}
}
}
}
この方法は、従来の方法で呼び出され、そうしてみてください...上記の方法で書かれたキャッチされ、これらのステップは、サブスレッドで行うことができ、最終的には成功した合成かどうかを確認するために、VideoView制御システムを介してビデオoutputVideoPathパスを再生することができます
要約手順
1.バッファオブジェクトを作成し、MediaCodec#BufferInfoオブジェクト
、2サンプルデータを読む検証データサイズ
情報3.完全bufferInfo
バッファの内容がマクサー書き込まれ4.
5.呼び出しMediaExtractor位前進を()、次に進みサンプルデータを、ステップ2-5のループ
6.リリースリソース
重要な考慮事項!!!!!!!!!!!!!!!
取る1.許可
2.ファイルは、サイズとして、合法的に抽出することを確認しますが、私はMediaExtractor.setDataSourceは()MediaExtractorを初期化することができなかった遭遇、我々は、ビデオのサイズを追加すると、0キロバイトであることが判明し
た合成効果に影響を与えます。3.タイムスタンプは、あなたが注意を払う必要がありますコンピュート
そこの質問やアイデアがあるか、ミスを見つけ、共有してください