安卓视频处理总结
2016-04-05 08:35
253 查看
04-04 16:55:57.099 28015-28195/com.rockylearnstorock.testcamera D/MediaHelper: {csd-1=java.nio.ByteArrayBuffer[position=0,limit=8,capacity=8], mime=video/avc, frame-rate=30, rotation-degrees=270, height=144, width=176, max-input-size=5755, durationUs=21107833, csd-0=java.nio.ByteArrayBuffer[position=0,limit=20,capacity=20]}
04-04 16:55:57.106 28015-28195/com.rockylearnstorock.testcamera D/MediaHelper: {mime=audio/mpeg, durationUs=256835918, encoder-delay=576, channel-count=2, encoder-padding=1681, sample-rate=44100, bit-rate=128000}
04-04 16:55:57.106 28015-28195/com.rockylearnstorock.testcamera E/MPEG4Writer: Unsupported mime 'audio/mpeg'
04-04 16:55:57.107 28015-28195/com.rockylearnstorock.testcamera W/System.err: java.lang.IllegalStateException: Failed to add the track to the muxer
04-04 16:55:57.111 28015-28195/com.rockylearnstorock.testcamera W/System.err: at android.media.MediaMuxer.nativeAddTrack(Native Method)
04-04 16:55:57.111 28015-28195/com.rockylearnstorock.testcamera W/System.err: at android.media.MediaMuxer.addTrack(MediaMuxer.java:294)
04-04 16:55:57.112 28015-28195/com.rockylearnstorock.testcamera W/System.err: at com.rockylearnstorock.testcamera.MediaHelper.combineAudioVideo(MediaHelper.java:181)
04-04 16:55:57.112 28015-28195/com.rockylearnstorock.testcamera W/System.err: at com.rockylearnstorock.testcamera.MainActivity$2.run(MainActivity.java:399)
04-04 16:55:57.112 28015-28195/com.rockylearnstorock.testcamera W/System.err: at java.lang.Thread.run(Thread.java:818)
Google "Unsupported mime 'audio/mpeg', 找到StackOverflow: Impossible to mix audio file and video file using MediaMuxer?
里面有个解释是
尝试将MP3换成m4a文件,合成,Negtive。
这个贴子里面还有个人发了一个github 例子,尝试, 合成的视频m4a的声音根本就没有加进去。Negtive.
Google " java.lang.IllegalStateException: Failed to add the track to the muxer", 返回的结果,都是" java.lang.IllegalStateException: Failed to stop the track to the muxer"。这个显然不是我要问的。
再看报错行
显示是将audioFormat添加到muxer时报错了。
关于MP4和MP3的MediaFormat,打印结果见上面黄色部分:
MP4:{csd-1=java.nio.ByteArrayBuffer[position=0,limit=8,capacity=8], mime=video/avc, frame-rate=30, rotation-degrees=270, height=144, width=176, max-input-size=5755, durationUs=21107833, csd-0=java.nio.ByteArrayBuffer[position=0,limit=20,capacity=20]}
MP3:{mime=audio/mpeg, durationUs=256835918, encoder-delay=576, channel-count=2, encoder-padding=1681, sample-rate=44100, bit-rate=128000}
两者的编码一个是avc, 另一个是mpeg.
根据我的理解, 不同的编码可能造成这个方法报错的原因。因为,“Unsupported mime 'audio/mpeg'”。
按照文中的思路,提取video和audio, 添加到MediaMuxer。生成的视频只有m4a中的声音,没有video原来的声音。
可能的原因:
尝试添加多个audio track 到MediaMuxer, google结果:Add second audio track to MediaMuxer
04-04 16:55:57.106 28015-28195/com.rockylearnstorock.testcamera D/MediaHelper: {mime=audio/mpeg, durationUs=256835918, encoder-delay=576, channel-count=2, encoder-padding=1681, sample-rate=44100, bit-rate=128000}
04-04 16:55:57.106 28015-28195/com.rockylearnstorock.testcamera E/MPEG4Writer: Unsupported mime 'audio/mpeg'
04-04 16:55:57.107 28015-28195/com.rockylearnstorock.testcamera W/System.err: java.lang.IllegalStateException: Failed to add the track to the muxer
04-04 16:55:57.111 28015-28195/com.rockylearnstorock.testcamera W/System.err: at android.media.MediaMuxer.nativeAddTrack(Native Method)
04-04 16:55:57.111 28015-28195/com.rockylearnstorock.testcamera W/System.err: at android.media.MediaMuxer.addTrack(MediaMuxer.java:294)
04-04 16:55:57.112 28015-28195/com.rockylearnstorock.testcamera W/System.err: at com.rockylearnstorock.testcamera.MediaHelper.combineAudioVideo(MediaHelper.java:181)
04-04 16:55:57.112 28015-28195/com.rockylearnstorock.testcamera W/System.err: at com.rockylearnstorock.testcamera.MainActivity$2.run(MainActivity.java:399)
04-04 16:55:57.112 28015-28195/com.rockylearnstorock.testcamera W/System.err: at java.lang.Thread.run(Thread.java:818)
Google "Unsupported mime 'audio/mpeg', 找到StackOverflow: Impossible to mix audio file and video file using MediaMuxer?
里面有个解释是
MediaMuxer does not transcode. If you write out an MPEG4 file, it will expect the video file to be MPEG4/AAC and the audio file to be an AAC file (m4a) as well. Once you feed it with an m4a, muxing will succeed.
尝试将MP3换成m4a文件,合成,Negtive。
这个贴子里面还有个人发了一个github 例子,尝试, 合成的视频m4a的声音根本就没有加进去。Negtive.
Google " java.lang.IllegalStateException: Failed to add the track to the muxer", 返回的结果,都是" java.lang.IllegalStateException: Failed to stop the track to the muxer"。这个显然不是我要问的。
再看报错行
int audioTrackIndex = muxer.addTrack(audioFormat); //MediaHelper.java:181 报错行
显示是将audioFormat添加到muxer时报错了。
关于MP4和MP3的MediaFormat,打印结果见上面黄色部分:
MP4:{csd-1=java.nio.ByteArrayBuffer[position=0,limit=8,capacity=8], mime=video/avc, frame-rate=30, rotation-degrees=270, height=144, width=176, max-input-size=5755, durationUs=21107833, csd-0=java.nio.ByteArrayBuffer[position=0,limit=20,capacity=20]}
MP3:{mime=audio/mpeg, durationUs=256835918, encoder-delay=576, channel-count=2, encoder-padding=1681, sample-rate=44100, bit-rate=128000}
两者的编码一个是avc, 另一个是mpeg.
根据我的理解, 不同的编码可能造成这个方法报错的原因。因为,“Unsupported mime 'audio/mpeg'”。
MediaExtractor audioExtractor = new MediaExtractor(); try { audioExtractor.setDataSource("/storage/emulated/0/DCIM/TestCamera/kisstherain.mp3"); } catch (IOException e) { e.printStackTrace(); Log.d("MediaHelper", "mp3 file can not be found"); return; } MediaFormat audioFormat = null; for(int i = 0; i < audioExtractor.getTrackCount(); i++){ audioFormat = audioExtractor.getTrackFormat(i); String mime = audioFormat.getString(MediaFormat.KEY_MIME); if(mime.startsWith("audio/")) { break; } } if(audioFormat == null){ Log.d("MediaHelper", "audioFormat is null"); return; }else{ Log.d("MediaHelper", audioFormat.toString()); } int audioTrackIndex = muxer.addTrack(audioFormat); //MediaHelper.java:181 报错行
尝试将MP3改为m4a文件,进行合并。
1.参考:Android中如何提取和生成mp4文件 (这是目前为止找到的最接近的答案)按照文中的思路,提取video和audio, 添加到MediaMuxer。生成的视频只有m4a中的声音,没有video原来的声音。
public static void combineAudioVideo(){ MediaMuxer muxer; try { muxer = new MediaMuxer("/storage/emulated/0/DCIM/TestCamera/temp.mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); } catch (IOException e) { e.printStackTrace(); Log.d("MediaHelper", "MediaMuxer init failed"); return; } // More often, the MediaFormat will be retrieved from MediaCodec.getOutputFormat() // or MediaExtractor.getTrackFormat(). MediaExtractor mMediaExtractor = new MediaExtractor(); try { mMediaExtractor.setDataSource(FileHelper.getOutputMediaFile(FileHelper.MEDIA_TYPE_VIDEO).getPath()); } catch (IOException e) { e.printStackTrace(); } int framerate = 0; MediaFormat videoFormat = null; for(int i = 0; i < mMediaExtractor.getTrackCount(); i++){ videoFormat = mMediaExtractor.getTrackFormat(i); String mime = videoFormat.getString(MediaFormat.KEY_MIME); framerate = videoFormat.getInteger(MediaFormat.KEY_FRAME_RATE); if(mime.startsWith("video/")) { mMediaExtractor.selectTrack(i); break; } } if(videoFormat == null){ Log.d("MediaHelper", "videoFormat is null"); return; }else { Log.d("MediaHelper", videoFormat.toString()); } MediaExtractor audioExtractor = new MediaExtractor(); try { audioExtractor.setDataSource("/storage/emulated/0/DCIM/TestCamera/1.m4a"); } catch (IOException e) { e.printStackTrace(); Log.d("MediaHelper", "mp3 file can not be found"); return; } int sampleRate = 0; MediaFormat audioFormat = null; for(int i = 0; i < audioExtractor.getTrackCount(); i++){ audioFormat = audioExtractor.getTrackFormat(i); String mime = audioFormat.getString(MediaFormat.KEY_MIME); sampleRate = audioFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE); if(mime.startsWith("audio/")) { audioExtractor.selectTrack(i); break; } } if(audioFormat == null){ Log.d("MediaHelper", "audioFormat is null"); return; }else{ Log.d("MediaHelper", audioFormat.toString()); } int audioTrackIndex = muxer.addTrack(audioFormat); int videoTrackIndex = muxer.addTrack(videoFormat); muxer.start(); MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); MediaCodec.BufferInfo audioInfo = new MediaCodec.BufferInfo(); info.presentationTimeUs = 0; ByteBuffer buffer = ByteBuffer.allocate(500*1024); ByteBuffer audioBuffer = ByteBuffer.allocate(500 * 1024); while(true) { int sampleSize = mMediaExtractor.readSampleData(buffer, 0); if(sampleSize < 0) { break; } int audioSampleSize = audioExtractor.readSampleData(audioBuffer, 0); if(audioSampleSize < 0){ break; } mMediaExtractor.advance(); audioExtractor.advance(); info.offset = 0; info.size = sampleSize; info.flags = MediaCodec.BUFFER_FLAG_SYNC_FRAME; info.presentationTimeUs += 1000*1000/framerate; audioInfo.offset = 0; audioInfo.size = audioSampleSize; audioInfo.flags = MediaCodec.BUFFER_FLAG_SYNC_FRAME; // audioInfo.presentationTimeUs += 1000 * 1000 / sampleRate; //暂提不明白sampleRate有什么作用,如果加了这句,生在的视频就无法播放 muxer.writeSampleData(videoTrackIndex, buffer, info); muxer.writeSampleData(audioTrackIndex, audioBuffer, audioInfo); } mMediaExtractor.release(); audioExtractor.release(); muxer.stop(); muxer.release(); }
可能的原因:
int audioTrackIndex = muxer.addTrack(audioFormat); //添加audio时,只有m4a文件audio,所以原来mp4文件中的就被覆盖了。
尝试添加多个audio track 到MediaMuxer, google结果:Add second audio track to MediaMuxer
相关文章推荐
- 代理模式
- .Net/C# 实现 中国移动 CMPP v3.0 ISMG <-> SP 收发短信的 SP 客户端 (CMPP SP Client)
- 1. Two Sum
- scrollTop兼容各个浏览器的办法
- Daily Sentence
- 生成验证码图片
- 心态不好,你将永远是个弱者!
- 敏捷开发之srcum
- python 之 前端初识 html
- nginx设置密码
- 2002
- 适配器模式
- C#多线程网页采集器(Spider)
- 宏碁台式机,如何设置u盘启动
- gc函数
- jQuery动画
- tcp三次握手四次挥手详解
- 【BZOJ1101】[POI2007]Zap【Mobius函数】
- 现代软件工程第五周作业
- 【BZOJ3172】单词,AC自动机练习