private MediaFormat selectTrack(MediaExtractor extractor) { int trackCount = extractor.getTrackCount(); Log.d(TAG, "trackCount :" + trackCount); MediaFormat format; for (int i = 0; i < trackCount; i++) { extractor.selectTrack(i); format = extractor.getTrackFormat(i); Log.d(TAG, "Track media format :" + format.toString()); String mime = format.getString(MediaFormat.KEY_MIME); if (mime.startsWith("video/")) { return format; } } return null; }
@TargetApi(16) private int selectTrack(MediaExtractor extractor, boolean audio) { int numTracks = extractor.getTrackCount(); for (int i = 0; i < numTracks; i++) { MediaFormat format = extractor.getTrackFormat(i); String mime = format.getString(MediaFormat.KEY_MIME); if (audio) { if (mime.startsWith("audio/")) { return i; } } else { if (mime.startsWith("video/")) { return i; } } } return -5; }
private int drainExtractor(long timeoutUs) { if (mIsExtractorEOS) return DRAIN_STATE_NONE; int trackIndex = mExtractor.getSampleTrackIndex(); if (trackIndex >= 0 && trackIndex != mTrackIndex) { return DRAIN_STATE_NONE; } final int result = mDecoder.dequeueInputBuffer(timeoutUs); if (result < 0) return DRAIN_STATE_NONE; if (trackIndex < 0) { mIsExtractorEOS = true; mDecoder.queueInputBuffer(result, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); return DRAIN_STATE_NONE; } final int sampleSize = mExtractor.readSampleData(mDecoderBuffers.getInputBuffer(result), 0); final boolean isKeyFrame = (mExtractor.getSampleFlags() & MediaExtractor.SAMPLE_FLAG_SYNC) != 0; mDecoder.queueInputBuffer(result, 0, sampleSize, mExtractor.getSampleTime(), isKeyFrame ? MediaCodec.BUFFER_FLAG_SYNC_FRAME : 0); mExtractor.advance(); return DRAIN_STATE_CONSUMED; }
private int drainExtractor(long timeoutUs) { if (mIsExtractorEOS) return DRAIN_STATE_NONE; int trackIndex = mExtractor.getSampleTrackIndex(); if (trackIndex >= 0 && trackIndex != mTrackIndex) { return DRAIN_STATE_NONE; } int result = mDecoder.dequeueInputBuffer(timeoutUs); if (result < 0) return DRAIN_STATE_NONE; if (trackIndex < 0) { mIsExtractorEOS = true; mDecoder.queueInputBuffer(result, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); return DRAIN_STATE_NONE; } int sampleSize = mExtractor.readSampleData(mDecoderInputBuffers[result], 0); boolean isKeyFrame = (mExtractor.getSampleFlags() & MediaExtractor.SAMPLE_FLAG_SYNC) != 0; mDecoder.queueInputBuffer(result, 0, sampleSize, mExtractor.getSampleTime(), isKeyFrame ? MediaCodec.BUFFER_FLAG_SYNC_FRAME : 0); mExtractor.advance(); return DRAIN_STATE_CONSUMED; }
public static TrackResult getFirstVideoAndAudioTrack(MediaExtractor extractor) { TrackResult trackResult = new TrackResult(); trackResult.mVideoTrackIndex = -1; trackResult.mAudioTrackIndex = -1; int trackCount = extractor.getTrackCount(); for (int i = 0; i < trackCount; i++) { MediaFormat format = extractor.getTrackFormat(i); String mime = format.getString(MediaFormat.KEY_MIME); if (trackResult.mVideoTrackIndex < 0 && mime.startsWith("video/")) { trackResult.mVideoTrackIndex = i; trackResult.mVideoTrackMime = mime; trackResult.mVideoTrackFormat = format; } else if (trackResult.mAudioTrackIndex < 0 && mime.startsWith("audio/")) { trackResult.mAudioTrackIndex = i; trackResult.mAudioTrackMime = mime; trackResult.mAudioTrackFormat = format; } if (trackResult.mVideoTrackIndex >= 0 && trackResult.mAudioTrackIndex >= 0) break; } if (trackResult.mVideoTrackIndex < 0 || trackResult.mAudioTrackIndex < 0) { throw new IllegalArgumentException("extractor does not contain video and/or audio tracks."); } return trackResult; }
@Override public void startSeeking() throws IOException { super.startSeeking(); Log.d(TAG, "start seeking state is: " + mState); if (mState == STATE_SEEKING) return; prepare(); setState(STATE_SEEKING); mInputDone = mOutputDone = false; mSeekDirection = SEEK_DIRECTION_FORWARD; mMediaCodec.start(); mSeekTargetTime = mExtractor.getSampleTime(); mExtractor.seekTo(mSeekTargetTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC); mIsSeeking = true; new Thread(mSeekRunnable, getClass().getSimpleName()).start(); }
public void seekTo(long presentationTime) { synchronized (mDecoderSync) { if (mIsSeeking) return; Log.d(TAG, "seek diff:" + (presentationTime - mSeekTargetTime)); mInputDone = mOutputDone = false; mSeekDirection = presentationTime >= mSeekTargetTime ? SEEK_DIRECTION_FORWARD : SEEK_DIRECTION_BACKWARD; if ((mSeekDirection == SEEK_DIRECTION_BACKWARD) || mSeekDirection == SEEK_DIRECTION_FORWARD && Math.abs(presentationTime - mLastSyncFrameTime) > mMaximumDifference) { mExtractor.seekTo(presentationTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC); mLastSyncFrameTime = mExtractor.getSampleTime(); } mSeekTargetTime = presentationTime; mIsSeeking = true; mDecoderSync.notifyAll(); } }
/** * 現在のfilePathを使ってExtractorを作成する */ private boolean readyExtractor(String filePath) { boolean isOk = false; mBufferinfo = new MediaCodec.BufferInfo(); try { mExtractor = new MediaExtractor(); mExtractor.setDataSource(filePath); isOk = true; } catch (IOException e) { e.printStackTrace(); Log.d(TAG, "Failed to setDataSource id:" + id); mVideoData = null; } return isOk; }
/** * Selects the video track, if any. * * @return the track index, or -1 if no video track is found. */ private static int selectTrack(MediaExtractor extractor) { // Select the first video track we find, ignore the rest. int numTracks = extractor.getTrackCount(); for (int i = 0; i < numTracks; i++) { MediaFormat format = extractor.getTrackFormat(i); String mime = format.getString(MediaFormat.KEY_MIME); if (mime.startsWith("video/")) { if (VERBOSE) { Log.d(TAG, "Extractor selected track " + i + " (" + mime + "): " + format); } return i; } } return -1; }
public boolean initExtractor(String filePath) throws IOException { decoding = false; audioExtractor = new MediaExtractor(); audioExtractor.setDataSource(filePath); for (int i = 0; i < audioExtractor.getTrackCount() && !mime.startsWith("audio/"); i++) { audioFormat = audioExtractor.getTrackFormat(i); mime = audioFormat.getString(MediaFormat.KEY_MIME); if (mime.startsWith("audio/")) { audioExtractor.selectTrack(i); } else { audioFormat = null; } } if (audioFormat != null && mime.equals("audio/mp4a-latm")) { isStereo = (audioFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT) == 2); sampleRate = audioFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE); return true; //audio decoder not supported } else { mime = ""; audioFormat = null; return false; } }
public boolean initExtractor(String filePath) throws IOException { decoding = false; videoExtractor = new MediaExtractor(); videoExtractor.setDataSource(filePath); for (int i = 0; i < videoExtractor.getTrackCount() && !mime.startsWith("video/"); i++) { videoFormat = videoExtractor.getTrackFormat(i); mime = videoFormat.getString(MediaFormat.KEY_MIME); if (mime.startsWith("video/")) { videoExtractor.selectTrack(i); } else { videoFormat = null; } } if (videoFormat != null && mime.equals("video/avc")) { width = videoFormat.getInteger(MediaFormat.KEY_WIDTH); height = videoFormat.getInteger(MediaFormat.KEY_HEIGHT); return true; //video decoder not supported } else { mime = ""; videoFormat = null; return false; } }
private int drainExtractor(long timeoutUs) { if (mIsExtractorEOS) return DRAIN_STATE_NONE; int trackIndex = mExtractor.getSampleTrackIndex(); if (trackIndex >= 0 && trackIndex != mTrackIndex) { return DRAIN_STATE_NONE; } int result = mDecoder.dequeueInputBuffer(timeoutUs); if (result < 0) return DRAIN_STATE_NONE; if (trackIndex < 0) { mIsExtractorEOS = true; mDecoder.queueInputBuffer(result, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); return DRAIN_STATE_NONE; } int sampleSize = mExtractor.readSampleData(MediaUtil.getInputBuffer(mDecoder, result), 0); boolean isKeyFrame = (mExtractor.getSampleFlags() & MediaExtractor.SAMPLE_FLAG_SYNC) != 0; mDecoder.queueInputBuffer(result, 0, sampleSize, mExtractor.getSampleTime(), isKeyFrame ? MediaCodec.BUFFER_FLAG_SYNC_FRAME : 0); mExtractor.advance(); return DRAIN_STATE_CONSUMED; }
public int retrieveFrameRate() { MediaExtractor extractor = new MediaExtractor(); int frameRate = -1; try { //Adjust data source as per the requirement if file, URI, etc. extractor.setDataSource(getPath()); int numTracks = extractor.getTrackCount(); for (int i = 0; i < numTracks; i++) { MediaFormat format = extractor.getTrackFormat(i); if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) { frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE); } } } catch (IOException e) { e.printStackTrace(); } finally { //Release stuff extractor.release(); } return frameRate; }
/** * 获取视频信息 * * @param url * @return */ public static long getDuration(String url) { try { MediaExtractor mediaExtractor = new MediaExtractor(); mediaExtractor.setDataSource(url); int videoExt = TrackUtils.selectVideoTrack(mediaExtractor); if(videoExt == -1){ videoExt = TrackUtils.selectAudioTrack(mediaExtractor); if(videoExt == -1){ return 0; } } MediaFormat mediaFormat = mediaExtractor.getTrackFormat(videoExt); long res = mediaFormat.containsKey(MediaFormat.KEY_DURATION) ? mediaFormat.getLong(MediaFormat.KEY_DURATION) : 0;//时长 mediaExtractor.release(); return res; } catch (Exception e) { return 0; } }
/** * 添加背景音乐 * * @param videoin 视频文件 * @param audioin 音频文件 * @param output 输出路径 * @param videoVolume 视频原声音音量(例:0.7为70%) * @param audioVolume 背景音乐音量(例:1.5为150%) * @param onEditorListener 回调监听 */ public static void music(String videoin, String audioin, String output, float videoVolume, float audioVolume, OnEditorListener onEditorListener) { MediaExtractor mediaExtractor = new MediaExtractor(); try { mediaExtractor.setDataSource(videoin); } catch (IOException e) { e.printStackTrace(); return; } int at = TrackUtils.selectAudioTrack(mediaExtractor); CmdList cmd = new CmdList(); cmd.append("ffmpeg").append("-y").append("-i").append(videoin); if (at == -1) { int vt = TrackUtils.selectVideoTrack(mediaExtractor); float duration = (float) mediaExtractor.getTrackFormat(vt).getLong(MediaFormat.KEY_DURATION) / 1000 / 1000; cmd.append("-ss").append("0").append("-t").append(duration).append("-i").append(audioin).append("-acodec").append("copy").append("-vcodec").append("copy"); } else { cmd.append("-i").append(audioin).append("-filter_complex") .append("[0:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,volume=" + videoVolume + "[a0];[1:a]aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo,volume=" + audioVolume + "[a1];[a0][a1]amix=inputs=2:duration=first[aout]") .append("-map").append("[aout]").append("-ac").append("2").append("-c:v") .append("copy").append("-map").append("0:v:0"); } cmd.append(output); mediaExtractor.release(); execCmd(cmd, 0, onEditorListener); }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override protected int handlePrepare(MediaExtractor media_extractor) { int track_index = selectTrack(media_extractor, "audio/"); if (track_index >= 0) { final MediaFormat format = media_extractor.getTrackFormat(track_index); mAudioChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT); mAudioSampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE); final int min_buf_size = AudioTrack.getMinBufferSize(mAudioSampleRate, (mAudioChannels == 1 ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO), AudioFormat.ENCODING_PCM_16BIT); final int max_input_size = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE); mAudioInputBufSize = min_buf_size > 0 ? min_buf_size * mAudioChannels * 2 : max_input_size; if (mAudioInputBufSize > max_input_size) mAudioInputBufSize = max_input_size; final int frameSizeInBytes = mAudioChannels * 2; mAudioInputBufSize = (mAudioInputBufSize / frameSizeInBytes) * frameSizeInBytes; if (DEBUG) Log.v(TAG, String.format("getMinBufferSize=%d,max_input_size=%d,mAudioInputBufSize=%d",min_buf_size, max_input_size, mAudioInputBufSize)); } return track_index; }
/** * @param media_extractor * @param trackIndex * @return */ protected MediaCodec internal_start_video(final MediaExtractor media_extractor, final int trackIndex) { if (DEBUG) Log.v(TAG, "internal_start_video:"); MediaCodec codec = null; if (trackIndex >= 0) { final MediaFormat format = media_extractor.getTrackFormat(trackIndex); final String mime = format.getString(MediaFormat.KEY_MIME); try { codec = MediaCodec.createDecoderByType(mime); codec.configure(format, mOutputSurface, null, 0); codec.start(); if (DEBUG) Log.v(TAG, "internal_start_video:codec started"); } catch (final IOException e) { Log.w(TAG, e); } } return codec; }
/** * @param media_extractor * @param trackIndex * @return */ protected MediaCodec internal_start_audio(final MediaExtractor media_extractor, final int trackIndex) { if (DEBUG) Log.v(TAG, "internal_start_audio:"); MediaCodec codec = null; if (trackIndex >= 0) { final MediaFormat format = media_extractor.getTrackFormat(trackIndex); final String mime = format.getString(MediaFormat.KEY_MIME); try { codec = MediaCodec.createDecoderByType(mime); codec.configure(format, null, null, 0); codec.start(); if (DEBUG) Log.v(TAG, "internal_start_audio:codec started"); // final ByteBuffer[] buffers = codec.getOutputBuffers(); int sz = buffers[0].capacity(); if (sz <= 0) sz = mAudioInputBufSize; if (DEBUG) Log.v(TAG, "AudioOutputBufSize:" + sz); mAudioOutTempBuf = new byte[sz]; } catch (final IOException e) { Log.w(TAG, e); } } return codec; }
/** * @param codec * @param extractor * @param inputBuffers * @param presentationTimeUs * @param isAudio */ protected boolean internal_process_input(final MediaCodec codec, final MediaExtractor extractor, final ByteBuffer[] inputBuffers, final long presentationTimeUs, final boolean isAudio) { // if (DEBUG) Log.v(TAG, "internal_process_input:presentationTimeUs=" + presentationTimeUs); boolean result = true; while (mIsRunning) { final int inputBufIndex = codec.dequeueInputBuffer(TIMEOUT_USEC); if (inputBufIndex == MediaCodec.INFO_TRY_AGAIN_LATER) break; if (inputBufIndex >= 0) { final int size = extractor.readSampleData(inputBuffers[inputBufIndex], 0); if (size > 0) { codec.queueInputBuffer(inputBufIndex, 0, size, presentationTimeUs, 0); } result = extractor.advance(); // return false if no data is available break; } } return result; }
/** * search first track index matched specific MIME * @param extractor * @param mimeType "video/" or "audio/" * @return track index, -1 if not found */ protected static final int selectTrack(final MediaExtractor extractor, final String mimeType) { final int numTracks = extractor.getTrackCount(); MediaFormat format; String mime; for (int i = 0; i < numTracks; i++) { format = extractor.getTrackFormat(i); mime = format.getString(MediaFormat.KEY_MIME); if (mime.startsWith(mimeType)) { if (DEBUG) { Log.d(TAG_STATIC, "Extractor selected track " + i + " (" + mime + "): " + format); } return i; } } return -1; }
/** * Selects the video track, if any. * * @return the track index, or -1 if no video track is found. */ private int selectTrack(MediaExtractor extractor) { // Select the first video track we find, ignore the rest. int numTracks = extractor.getTrackCount(); for (int i = 0; i < numTracks; i++) { MediaFormat format = extractor.getTrackFormat(i); String mime = format.getString(MediaFormat.KEY_MIME); if (mime.startsWith("video/")) { if (VERBOSE) { Log.d(TAG, "Extractor selected track " + i + " (" + mime + "): " + format); } return i; } } return -1; }
private static void concatVideoListFromMediaCodec(List<String> pathList, String destinationVideoFilePath, int videoRotation, ConcatMediaCallback concatMediaCallback) throws IOException { MediaExtractor extractor = new MediaExtractor(); MediaFormat format = null; extractor.setDataSource(pathList.get(0)); int numTracks = extractor.getTrackCount(); // find and select the first audio track present in the file. for (int i = 0; i < numTracks; i++) { format = extractor.getTrackFormat(i); if (format.getString(MediaFormat.KEY_MIME).startsWith("audio/")) { extractor.selectTrack(i); break; } } MediaCodec mediaCodec = MediaCodec.createDecoderByType(format.getString(MediaFormat.KEY_MIME)); mediaCodec.configure(format, null, null, 0); mediaCodec.start(); }
/** * Initialize a MediaExctractor if needed * @throws IOException */ private void initMediaExtractor() throws IOException{ String filePath = Environment.getExternalStorageDirectory().getPath() + "/rpi960mal810.h264"; //String filePath = "/storage/sdcard/rpi960mal810.h264"; //String filePath = Environment.getExternalStorageDirectory().getPath() + "/somefile2.264"; //??? //String filePath = "/storage/external_SD/movies/scut1.avi"; //??? //String filePath = Environment.getExternalStorageDirectory().getPath() + "/vv/cat.h264"; //String filePath = Environment.getExternalStorageDirectory().getPath() + "/vv/ravi2.264"; //String filePath = Environment.getExternalStorageDirectory().getPath() + "/testfile.264"; //String filePath = Environment.getExternalStorageDirectory().getPath() + "/vv/cat90.h264"; File f = new File(filePath); boolean ext = f.exists(); mediaExtractor = new MediaExtractor(); mediaExtractor.setDataSource(filePath); int trackCount = mediaExtractor.getTrackCount(); if(trackCount != 1){ // throw new RuntimeException("TrackCount = " + trackCount + ". Only Single Track is supported"); } mediaExtractor.selectTrack(0); }
public void initStream() throws Exception { mLock.lock(); try { mExtractor = new MediaExtractor(); if (!TextUtils.isEmpty(mPath)) { mExtractor.setDataSource(mPath); } else if (mUri != null) { mExtractor.setDataSource(mContext, mUri, null); } else { throw new IOException(); } } catch (Exception e) {//IOException throw e; } finally { mLock.unlock(); } initConfig(); }
/** * 该音频是否符合采样率是sampleRate,通道数是channelCount,值为-1表示忽略该条件 * * @param audioFile * @param sampleRate * @param channelCount * @return */ public static boolean isMatchAudioFormat(String audioFile, int sampleRate,int channelCount){ MediaExtractor mex = new MediaExtractor(); try { mex.setDataSource(audioFile); } catch (IOException e) { e.printStackTrace(); } MediaFormat mf = mex.getTrackFormat(0); boolean result = true; if(sampleRate != -1){ result = sampleRate == mf.getInteger(MediaFormat.KEY_SAMPLE_RATE); } if(result && channelCount != -1){ result = channelCount == mf.getInteger(MediaFormat.KEY_CHANNEL_COUNT); } mex.release(); return result; }
public MP4Encorder(Session session){ mediaExtractor = new MediaExtractor(); try { mediaExtractor.setDataSource(session.getVideoPath()); } catch (IOException e) { e.printStackTrace(); } for(int i = 0; i < mediaExtractor.getTrackCount(); i++) { MediaFormat format = mediaExtractor.getTrackFormat(i); String mime = format.getString(MediaFormat.KEY_MIME); if (!mime.startsWith("video/")) { continue; } framerate = format.getInteger(MediaFormat.KEY_FRAME_RATE); mediaExtractor.selectTrack(i); session.getVideoQuality().setmFrameRate(framerate); } }
public void prepare(String path) { mExtractor = new MediaExtractor(); try { mExtractor.setDataSource(path); } catch (IOException e) { e.printStackTrace(); } int tracks = mExtractor.getTrackCount(); for (int i = 0; i < tracks; i++) { MediaFormat format = mExtractor.getTrackFormat(i); String mime = format.getString(MediaFormat.KEY_MIME); Logs.i(TAG, "mime = " + mime); } mExtractor.selectTrack(0); mAudioBuffer = ByteBuffer.allocate(1024); next();; }
private MediaExtractor prepareAudio(String path) { MediaExtractor mExtractor = new MediaExtractor(); try { mExtractor.setDataSource(path); } catch (IOException e) { e.printStackTrace(); } int tracks = mExtractor.getTrackCount(); for (int i = 0; i < tracks; i++) { MediaFormat format = mExtractor.getTrackFormat(i); String mime = format.getString(MediaFormat.KEY_MIME); Logs.i(TAG, "mime = " + mime); } mExtractor.selectTrack(0); return mExtractor; }