我有一个从麦克风录制的3gp文件和一个mp4视频文件。 我想将音频文件和视频文件复制到mp4文件并保存。 我搜索了很多,但没有找到任何有助于使用Android的MediaMuxer api的东西。 MediaMuxer api
更新:这是我的方法,复用两个文件,我有一个例外。 原因是目标mp4文件没有任何轨道! someOne可以帮我添加音频和视频轨道到muxer ??
例外
java.lang.IllegalStateException: Failed to stop the muxer
我的代码:
private void cloneMediaUsingMuxer( String dstMediaPath) throws IOException {
// Set up MediaExtractor to read from the source.
MediaExtractor soundExtractor = new MediaExtractor();
soundExtractor.setDataSource(audioFilePath);
MediaExtractor videoExtractor = new MediaExtractor();
AssetFileDescriptor afd2 = getAssets().openFd("Produce.MP4");
videoExtractor.setDataSource(afd2.getFileDescriptor() , afd2.getStartOffset(),afd2.getLength());
//PATH
//extractor.setDataSource();
int trackCount = soundExtractor.getTrackCount();
int trackCount2 = soundExtractor.getTrackCount();
//assertEquals("wrong number of tracks", expectedTrackCount, trackCount);
// Set up MediaMuxer for the destination.
MediaMuxer muxer;
muxer = new MediaMuxer(dstMediaPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// Set up the tracks.
HashMap<Integer, Integer> indexMap = new HashMap<Integer, Integer>(trackCount);
for (int i = 0; i < trackCount; i++) {
soundExtractor.selectTrack(i);
MediaFormat SoundFormat = soundExtractor.getTrackFormat(i);
int dstIndex = muxer.addTrack(SoundFormat);
indexMap.put(i, dstIndex);
}
HashMap<Integer, Integer> indexMap2 = new HashMap<Integer, Integer>(trackCount2);
for (int i = 0; i < trackCount2; i++) {
videoExtractor.selectTrack(i);
MediaFormat videoFormat = videoExtractor.getTrackFormat(i);
int dstIndex2 = muxer.addTrack(videoFormat);
indexMap.put(i, dstIndex2);
}
// Copy the samples from MediaExtractor to MediaMuxer.
boolean sawEOS = false;
int bufferSize = MAX_SAMPLE_SIZE;
int frameCount = 0;
int offset = 100;
ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize);
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
MediaCodec.BufferInfo bufferInfo2 = new MediaCodec.BufferInfo();
muxer.start();
while (!sawEOS) {
bufferInfo.offset = offset;
bufferInfo.size = soundExtractor.readSampleData(dstBuf, offset);
bufferInfo2.offset = offset;
bufferInfo2.size = videoExtractor.readSampleData(dstBuf, offset);
if (bufferInfo.size < 0) {
sawEOS = true;
bufferInfo.size = 0;
bufferInfo2.size = 0;
}else if(bufferInfo2.size < 0){
sawEOS = true;
bufferInfo.size = 0;
bufferInfo2.size = 0;
}
else {
bufferInfo.presentationTimeUs = soundExtractor.getSampleTime();
bufferInfo2.presentationTimeUs = videoExtractor.getSampleTime();
//bufferInfo.flags = extractor.getSampleFlags();
int trackIndex = soundExtractor.getSampleTrackIndex();
int trackIndex2 = videoExtractor.getSampleTrackIndex();
muxer.writeSampleData(indexMap.get(trackIndex), dstBuf,
bufferInfo);
soundExtractor.advance();
videoExtractor.advance();
frameCount++;
}
}
Toast.makeText(getApplicationContext(),"f:"+frameCount,Toast.LENGTH_SHORT).show();
muxer.stop();
muxer.release();
}
更新2:问题解决了!检查我的问题的答案。
感谢您的帮助
答案 0 :(得分:17)
音频和视频文件的音轨存在问题。 他们走了,我的代码一切正常,但现在你可以用它来合并一个音频文件和一个视频文件。
代码:
[JAVA-4, JAVA-3, JAVA-2, CPP-2, JAVA-1, CPP-1, C]
}
答案 1 :(得分:1)
感谢mohamad ali gharat的回答,这对我帮助太大了。 但是我对代码工作做了一些改变, 第一:我改变了
videoExtractor.setDataSource
来videoExtractor.setDataSource(Environment.getExternalStorageDirectory().getPath() + "/Produce.MP4");
从SDCard
加载视频。
第二:我错了
videoBufferInfo.flags = videoExtractor.getSampleFlags();
所以将其改为
videoBufferInfo.flags = MediaCodec.BUFFER_FLAG_SYNC_FRAME;
使其工作,因为此链接说Android MediaMuxer failed to stop
答案 2 :(得分:0)
你需要在ffmpeg工作。这是一个帮助的链接:
ffmpeg需要Android上的NDK。
一旦你有了这个工作,你就可以使用ffmpeg将音频和视频混合在一起了。这是一个用2个视频文件做的问题的链接(答案应该类似)。
FFMPEG mux video and audio (from another video) - mapping issue