如题,我是参考 http://blog.51cto.com/ticktick/1710743 改写了一下,但是MediaFormat是通过手动创建的,通过Extractor解出来的Buffer手动的创建MediaFormat,遇到几个问题:将第一帧写入MediaFormat后手动调用MediaExtractor的advance方法运行后直接crash,error是muxer fail to stop 2.SPS和PPS写入MediaFormat后是否还需要再通过muxer写入,不写入的话时间戳会不会有问题?
2条回答 默认 最新
- 尤教授 2018-11-06 02:25关注
public class MainActivity extends Activity {
private static final String SDCARD_PATH = Environment.getExternalStorageDirectory().getPath(); private static final String INPUT_FILEPATH = SDCARD_PATH + "/input.mp4"; private static final String OUTPUT_FILEPATH = SDCARD_PATH + "/output.mp4"; private int i = 0; private TextView mLogView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLogView = (TextView) findViewById(R.id.LogView); new Thread(new Runnable() { @Override public void run() { try { transcode(INPUT_FILEPATH, OUTPUT_FILEPATH); } catch (IOException e) { e.printStackTrace(); logout(e.getMessage()); } } }).start(); } protected boolean transcode(String input, String output) throws IOException { logout("start processing..."); MediaMuxer muxer = null; MediaExtractor extractor = new MediaExtractor(); extractor.setDataSource(input); logout("start demuxer: " + input); MediaFormat videoFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720); extractor.selectTrack(0);
// if (muxer == null) {
// logout("no video found !");
// return false;
// }BufferInfo info = new BufferInfo(); info.presentationTimeUs = 0; ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024 * 2); int i = - 1; while (true) { i++; int sampleSize = extractor.readSampleData(buffer, 0); if (sampleSize < 0) { logout("read sample data failed , break !"); break; } if (i == 0 ){ byte[] sps_header = new byte[sampleSize]; for (int j = 0;j < sampleSize;j++){ sps_header[j] = buffer.array()[sampleSize]; } //SPS videoFormat.setByteBuffer("csd-0", ByteBuffer.wrap(sps_header)); extractor.advance(); continue; }else if (i == 1){ //PPS byte[] pps_header = new byte[sampleSize]; for (int j = 0; j < sampleSize; j++){ pps_header[j] = buffer.array()[sampleSize]; } videoFormat.setByteBuffer("csd-1",ByteBuffer.wrap(pps_header)); videoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar); videoFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1920 * 1080); videoFormat.setInteger(MediaFormat.KEY_CAPTURE_RATE, 25); muxer = new MediaMuxer(output,OutputFormat.MUXER_OUTPUT_MPEG_4); muxer.addTrack(videoFormat); muxer.start(); continue; } Log.d("xiaxingyu","i = " + i); info.offset = 0; info.size = sampleSize; info.flags = extractor.getSampleFlags(); info.presentationTimeUs = extractor.getSampleTime(); boolean keyframe = (info.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) > 0; logout("write sample " + keyframe + ", " + sampleSize + ", " + info.presentationTimeUs); muxer.writeSampleData(0, buffer, info); extractor.advance(); } extractor.release(); muxer.stop(); muxer.release(); logout("process success !"); return true; } private void logout(final String content) { runOnUiThread(new Runnable() { @Override public void run() { Log.i("MediaDemo", content); mLogView.setText(mLogView.getText() + "\n" + content); } }); }
}
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报