Java Code Examples for android.media.MediaFormat#getLong()

The following examples show how to use android.media.MediaFormat#getLong() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TrackTranscoder.java    From LiTr with BSD 2-Clause "Simplified" License 6 votes vote down vote up
TrackTranscoder(@NonNull MediaSource mediaSource,
                int sourceTrack,
                @NonNull MediaTarget mediaTarget,
                int targetTrack,
                @Nullable MediaFormat targetFormat,
                @Nullable Renderer renderer,
                @Nullable Decoder decoder,
                @Nullable Encoder encoder) {
    this.mediaSource = mediaSource;
    this.sourceTrack = sourceTrack;
    this.targetTrack = targetTrack;
    this.mediaMuxer = mediaTarget;
    this.targetFormat = targetFormat;
    this.renderer = renderer;
    this.decoder = decoder;
    this.encoder = encoder;

    MediaFormat sourceMedia = mediaSource.getTrackFormat(sourceTrack);
    if (sourceMedia.containsKey(MediaFormat.KEY_DURATION)) {
        duration = sourceMedia.getLong(MediaFormat.KEY_DURATION);
        if (targetFormat != null) {
            targetFormat.setLong(MediaFormat.KEY_DURATION, duration);
        }
    }
}
 
Example 2
Source File: MediaMoviePlayer.java    From AudioVideoPlayerSample with Apache License 2.0 6 votes vote down vote up
/**
 * @param sourceFile
 * @return first video track index, -1 if not found
 */
protected int internalPrepareVideo(final String sourceFile) {
	int trackIndex = -1;
	mVideoMediaExtractor = new MediaExtractor();
	try {
		mVideoMediaExtractor.setDataSource(sourceFile);
		trackIndex = selectTrack(mVideoMediaExtractor, "video/");
		if (trackIndex >= 0) {
			mVideoMediaExtractor.selectTrack(trackIndex);
	        final MediaFormat format = mVideoMediaExtractor.getTrackFormat(trackIndex);
        	mVideoWidth = format.getInteger(MediaFormat.KEY_WIDTH);
        	mVideoHeight = format.getInteger(MediaFormat.KEY_HEIGHT);
        	mDuration = format.getLong(MediaFormat.KEY_DURATION);

			if (DEBUG) Log.v(TAG, String.format("format:size(%d,%d),duration=%d,bps=%d,framerate=%f,rotation=%d",
				mVideoWidth, mVideoHeight, mDuration, mBitrate, mFrameRate, mRotation));
		}
	} catch (final IOException e) {
		Log.w(TAG, e);
	}
	return trackIndex;
}
 
Example 3
Source File: MediaVideoPlayer.java    From AudioVideoPlayerSample with Apache License 2.0 6 votes vote down vote up
/**
 * @param sourceFile
 * @return first video track index, -1 if not found
 */
protected int internalPrepareVideo(final String sourceFile) {
	int trackIndex = -1;
	mVideoMediaExtractor = new MediaExtractor();
	try {
		mVideoMediaExtractor.setDataSource(sourceFile);
		trackIndex = selectTrack(mVideoMediaExtractor, "video/");
		if (trackIndex >= 0) {
			mVideoMediaExtractor.selectTrack(trackIndex);
	        final MediaFormat format = mVideoMediaExtractor.getTrackFormat(trackIndex);
        	mVideoWidth = format.getInteger(MediaFormat.KEY_WIDTH);
        	mVideoHeight = format.getInteger(MediaFormat.KEY_HEIGHT);
        	mDuration = format.getLong(MediaFormat.KEY_DURATION);

			if (DEBUG) Log.v(TAG, String.format("format:size(%d,%d),duration=%d,bps=%d,framerate=%f,rotation=%d",
				mVideoWidth, mVideoHeight, mDuration, mBitrate, mFrameRate, mRotation));
		}
	} catch (final IOException e) {
		Log.w(TAG, e);
	}
	return trackIndex;
}
 
Example 4
Source File: TranscoderUtils.java    From LiTr with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Estimates video track bitrate. On many devices bitrate value is not specified in {@link MediaFormat} for video track.
 * Since not all data required for accurate estimation is available, this method makes several assumptions:
 *  - if multiple video tracks are present, average per-pixel bitrate is assumed to be the same for all tracks
 *  - if either bitrate or duration are not specified for a track, its size is not accounted for
 *
 * @param mediaSource {@link MediaSource} which contains the video track
 * @param trackIndex index of video track
 * @return estimated bitrate in bits per second
 */
public static int estimateVideoTrackBitrate(@NonNull MediaSource mediaSource, int trackIndex) {
    MediaFormat videoTrackFormat = mediaSource.getTrackFormat(trackIndex);
    if (videoTrackFormat.containsKey(MediaFormat.KEY_BIT_RATE)) {
        return videoTrackFormat.getInteger(MediaFormat.KEY_BIT_RATE);
    }

    long unallocatedSize = mediaSource.getSize();
    long totalPixels = 0;
    int trackCount = mediaSource.getTrackCount();
    for (int track = 0; track < trackCount; track++) {
        MediaFormat trackFormat = mediaSource.getTrackFormat(track);
        if (trackFormat.containsKey(MediaFormat.KEY_MIME)) {
            if (trackFormat.containsKey(MediaFormat.KEY_BIT_RATE) && trackFormat.containsKey(MediaFormat.KEY_DURATION)) {
                int bitrate = trackFormat.getInteger(MediaFormat.KEY_BIT_RATE);
                long duration = trackFormat.getLong(MediaFormat.KEY_DURATION);
                unallocatedSize -= bitrate * TimeUnit.MICROSECONDS.toSeconds(duration) / 8;
            } else {
                String mimeType = trackFormat.getString(MediaFormat.KEY_MIME);
                if (mimeType.startsWith("video")) {
                    totalPixels += trackFormat.getInteger(MediaFormat.KEY_WIDTH)
                        * trackFormat.getInteger(MediaFormat.KEY_HEIGHT)
                        * TimeUnit.MICROSECONDS.toSeconds(trackFormat.getLong(MediaFormat.KEY_DURATION));
                }
            }
        }
    }

    long trackPixels = videoTrackFormat.getInteger(MediaFormat.KEY_WIDTH)
        * videoTrackFormat.getInteger(MediaFormat.KEY_HEIGHT)
        * TimeUnit.MICROSECONDS.toSeconds(videoTrackFormat.getLong(MediaFormat.KEY_DURATION));

    long trackSize = unallocatedSize * trackPixels / totalPixels;

    return (int) (trackSize * 8 / TimeUnit.MICROSECONDS.toSeconds(videoTrackFormat.getLong(MediaFormat.KEY_DURATION)));
}
 
Example 5
Source File: TranscoderUtils.java    From LiTr with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private static long getDuration(@NonNull MediaFormat trackFormat) {
    long duration = -1;
    if (trackFormat.containsKey(MediaFormat.KEY_DURATION)) {
        duration = trackFormat.getLong(MediaFormat.KEY_DURATION);
    }
    return duration;
}
 
Example 6
Source File: AudioTransCoder.java    From SimpleVideoEditor with Apache License 2.0 5 votes vote down vote up
private void prepare() throws IOException {
    extractor = new MediaExtractor();
    extractor.setDataSource(mInputFile.getAbsolutePath());
    int numTracks = extractor.getTrackCount();
    for (int i = 0; i < numTracks; i++) {
        MediaFormat format = extractor.getTrackFormat(i);
        String mine = format.getString(MediaFormat.KEY_MIME);
        if (!TextUtils.isEmpty(mine) && mine.startsWith("audio")) {
            extractor.selectTrack(i);
            if (mDurationMs == 0) {
                try {
                    mDurationMs = format.getLong(MediaFormat.KEY_DURATION) / 1000;
                } catch (Exception e) {
                    e.printStackTrace();
                    MediaPlayer mediaPlayer = new MediaPlayer();
                    mediaPlayer.setDataSource(mInputFile.getAbsolutePath());
                    mediaPlayer.prepare();
                    mDurationMs = mediaPlayer.getDuration();
                    mediaPlayer.release();
                }
            }

            if (mDurationMs == 0) {
                throw new IllegalStateException("We can not get duration info from input file: " + mInputFile);
            }

            decoder = MediaCodec.createDecoderByType(mine);
            decoder.configure(format, null, null, 0);
            decoder.start();
            break;
        }
    }
}
 
Example 7
Source File: MediaMoviePlayer.java    From libcommon with Apache License 2.0 5 votes vote down vote up
/**
 * @param source
 * @return first video track index, -1 if not found
 */
@SuppressLint("NewApi")
protected int internal_prepare_video(final Object source) throws IOException {
	int trackindex = -1;
	mVideoMediaExtractor = new MediaExtractor();
	if (source instanceof String) {
		mVideoMediaExtractor.setDataSource((String)source);
	} else if (source instanceof AssetFileDescriptor) {
		if (BuildCheck.isAndroid7()) {
			mVideoMediaExtractor.setDataSource((AssetFileDescriptor)source);
		} else {
			mVideoMediaExtractor.setDataSource(((AssetFileDescriptor)source).getFileDescriptor());
		}
	} else {
		// ここには来ないけど
		throw new IllegalArgumentException("unknown source type:source=" + source);
	}
	trackindex = selectTrack(mVideoMediaExtractor, "video/");
	if (trackindex >= 0) {
		mVideoMediaExtractor.selectTrack(trackindex);
		final MediaFormat format = mVideoMediaExtractor.getTrackFormat(trackindex);
		mVideoWidth = format.getInteger(MediaFormat.KEY_WIDTH);
		mVideoHeight = format.getInteger(MediaFormat.KEY_HEIGHT);
		mDuration = format.getLong(MediaFormat.KEY_DURATION);

		if (DEBUG) Log.v(TAG, String.format("format:size(%d,%d),duration=%d,bps=%d,framerate=%f,rotation=%d",
			mVideoWidth, mVideoHeight, mDuration, mBitrate, mFrameRate, mRotation));
	}
	return trackindex;
}
 
Example 8
Source File: Track.java    From K-Sonic with MIT License 5 votes vote down vote up
public void initConfig() throws Exception {
    if (mCurrentState == STATE_PLAYBACK_COMPLETED) {
        mExtractor.seekTo(((long) jMsec * 1000), MediaExtractor.SEEK_TO_CLOSEST_SYNC);
        //归零
        jMsec = 0;
    }
    mLock.lock();
    try {
        MediaFormat oFormat = mExtractor.getTrackFormat(TRACK_NUM);
        //oFormat NullPointerException
        int sampleRate = oFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
        int channelCount = oFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
        //Deal with mono ,, Some models do not support
        if (isJMono = channelCount == 1)
            oFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, channelCount = 2);
        String mime = oFormat.getString(MediaFormat.KEY_MIME);
        //Deal with mime ,, Some models will mime identification into ffmpeg
        if ("audio/ffmpeg".equals(mime))
            oFormat.setString(MediaFormat.KEY_MIME, mime = "audio/mpeg");
        mDuration = oFormat.getLong(MediaFormat.KEY_DURATION);

        Log.v(TAG_TRACK, "Sample rate: " + sampleRate);
        Log.v(TAG_TRACK, "Mime type: " + mime);

        initDevice(sampleRate, channelCount);
        mExtractor.selectTrack(TRACK_NUM);
        mCodec = MediaCodec.createDecoderByType(mime);
        mCodec.configure(oFormat, null, null, 0);
    } catch (Exception e) {//IOException
        throw e;
    } finally {
        mLock.unlock();
    }
}
 
Example 9
Source File: VideoPlayer.java    From media-for-mobile with Apache License 2.0 5 votes vote down vote up
private boolean initWithTrackOfInterest(String startsWith) {
    int numTracks = extractor.getTrackCount();

    for (int i = 0; i < numTracks; i++) {
        MediaFormat mediaFormat = extractor.getTrackFormat(i);
        String mime = mediaFormat.getString(MediaFormat.KEY_MIME);

        if (mime.startsWith(startsWith)) {
            trackNumber = i;

            extractor.selectTrack(trackNumber);

            try {
                codec = MediaCodec.createDecoderByType(mime);
                codec.configure(mediaFormat, surface, null, 0);
            } catch (IOException e) {
                e.printStackTrace();
            }

            long duration = (int) mediaFormat.getLong(MediaFormat.KEY_DURATION);

            Message msg = uiHandler.obtainMessage(DURATION_CHANGED, duration / 1000);
            uiHandler.sendMessage(msg);

            return true;
        }
    }

    return false;
}
 
Example 10
Source File: VideoThumbnailsExtractor.java    From mollyim-android with GNU General Public License v3.0 4 votes vote down vote up
static void extractThumbnails(final @NonNull MediaInput input,
                              final int thumbnailCount,
                              final int thumbnailResolution,
                              final @NonNull Callback callback)
{
  MediaExtractor extractor     = null;
  MediaCodec     decoder       = null;
  OutputSurface  outputSurface = null;
  try {
    extractor = input.createExtractor();
    MediaFormat mediaFormat = null;
    for (int index = 0; index < extractor.getTrackCount(); ++index) {
      if (extractor.getTrackFormat(index).getString(MediaFormat.KEY_MIME).startsWith("video/")) {
        extractor.selectTrack(index);
        mediaFormat = extractor.getTrackFormat(index);
        break;
      }
    }
    if (mediaFormat != null) {
      final String mime     = mediaFormat.getString(MediaFormat.KEY_MIME);
      final int    rotation = mediaFormat.containsKey(MediaFormat.KEY_ROTATION) ? mediaFormat.getInteger(MediaFormat.KEY_ROTATION) : 0;
      final int    width    = mediaFormat.getInteger(MediaFormat.KEY_WIDTH);
      final int    height   = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);
      final int    outputWidth;
      final int    outputHeight;

      if (width < height) {
        outputWidth  = thumbnailResolution;
        outputHeight = height * outputWidth / width;
      } else {
        outputHeight = thumbnailResolution;
        outputWidth  = width * outputHeight / height;
      }

      final int outputWidthRotated;
      final int outputHeightRotated;

      if ((rotation % 180 == 90)) {
        //noinspection SuspiciousNameCombination
        outputWidthRotated = outputHeight;
        //noinspection SuspiciousNameCombination
        outputHeightRotated = outputWidth;
      } else {
        outputWidthRotated  = outputWidth;
        outputHeightRotated = outputHeight;
      }

      Log.i(TAG, "video: " + width + "x" + height + " " + rotation);
      Log.i(TAG, "output: " + outputWidthRotated + "x" + outputHeightRotated);

      outputSurface = new OutputSurface(outputWidthRotated, outputHeightRotated, true);

      decoder = MediaCodec.createDecoderByType(mime);
      decoder.configure(mediaFormat, outputSurface.getSurface(), null, 0);
      decoder.start();

      long duration = 0;

      if (mediaFormat.containsKey(MediaFormat.KEY_DURATION)) {
        duration = mediaFormat.getLong(MediaFormat.KEY_DURATION);
      } else {
        Log.w(TAG, "Video is missing duration!");
      }

      callback.durationKnown(duration);

      doExtract(extractor, decoder, outputSurface, outputWidthRotated, outputHeightRotated, duration, thumbnailCount, callback);
    }
  } catch (IOException | TranscodingException e) {
    Log.w(TAG, e);
    callback.failed();
  } finally {
    if (outputSurface != null) {
      outputSurface.release();
    }
    if (decoder != null) {
      decoder.stop();
      decoder.release();
    }
    if (extractor != null) {
      extractor.release();
    }
  }
}
 
Example 11
Source File: VideoTrackConverter.java    From mollyim-android with GNU General Public License v3.0 4 votes vote down vote up
@RequiresApi(23)
private VideoTrackConverter(
        final @NonNull MediaExtractor videoExtractor,
        final int videoInputTrack,
        final long timeFrom,
        final long timeTo,
        final int videoResolution,
        final int videoBitrate,
        final @NonNull String videoCodec) throws IOException, TranscodingException {

    mTimeFrom = timeFrom;
    mTimeTo = timeTo;
    mVideoExtractor = videoExtractor;

    final MediaCodecInfo videoCodecInfo = MediaConverter.selectCodec(videoCodec);
    if (videoCodecInfo == null) {
        // Don't fail CTS if they don't have an AVC codec (not here, anyway).
        Log.e(TAG, "Unable to find an appropriate codec for " + videoCodec);
        throw new FileNotFoundException();
    }
    if (VERBOSE) Log.d(TAG, "video found codec: " + videoCodecInfo.getName());

    final MediaFormat inputVideoFormat = mVideoExtractor.getTrackFormat(videoInputTrack);

    mInputDuration = inputVideoFormat.containsKey(MediaFormat.KEY_DURATION) ? inputVideoFormat.getLong(MediaFormat.KEY_DURATION) : 0;

    final int rotation = inputVideoFormat.containsKey(MediaFormat.KEY_ROTATION) ? inputVideoFormat.getInteger(MediaFormat.KEY_ROTATION) : 0;
    final int width = inputVideoFormat.containsKey(MEDIA_FORMAT_KEY_DISPLAY_WIDTH)
                      ? inputVideoFormat.getInteger(MEDIA_FORMAT_KEY_DISPLAY_WIDTH)
                      : inputVideoFormat.getInteger(MediaFormat.KEY_WIDTH);
    final int height = inputVideoFormat.containsKey(MEDIA_FORMAT_KEY_DISPLAY_HEIGHT)
                       ? inputVideoFormat.getInteger(MEDIA_FORMAT_KEY_DISPLAY_HEIGHT)
                       : inputVideoFormat.getInteger(MediaFormat.KEY_HEIGHT);
    int outputWidth = width;
    int outputHeight = height;
    if (outputWidth < outputHeight) {
        outputWidth = videoResolution;
        outputHeight = height * outputWidth / width;
    } else {
        outputHeight = videoResolution;
        outputWidth = width * outputHeight / height;
    }
    // many encoders do not work when height and width are not multiple of 16 (also, some iPhones do not play some heights)
    outputHeight = (outputHeight + 7) & ~0xF;
    outputWidth = (outputWidth + 7) & ~0xF;

    final int outputWidthRotated;
    final int outputHeightRotated;
    if ((rotation % 180 == 90)) {
        //noinspection SuspiciousNameCombination
        outputWidthRotated = outputHeight;
        //noinspection SuspiciousNameCombination
        outputHeightRotated = outputWidth;
    } else {
        outputWidthRotated = outputWidth;
        outputHeightRotated = outputHeight;
    }

    final MediaFormat outputVideoFormat = MediaFormat.createVideoFormat(videoCodec, outputWidthRotated, outputHeightRotated);

    // Set some properties. Failing to specify some of these can cause the MediaCodec
    // configure() call to throw an unhelpful exception.
    outputVideoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    outputVideoFormat.setInteger(MediaFormat.KEY_BIT_RATE, videoBitrate);
    outputVideoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, OUTPUT_VIDEO_FRAME_RATE);
    outputVideoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, OUTPUT_VIDEO_IFRAME_INTERVAL);
    if (VERBOSE) Log.d(TAG, "video format: " + outputVideoFormat);

    // Create a MediaCodec for the desired codec, then configure it as an encoder with
    // our desired properties. Request a Surface to use for input.
    final AtomicReference<Surface> inputSurfaceReference = new AtomicReference<>();
    mVideoEncoder = createVideoEncoder(videoCodecInfo, outputVideoFormat, inputSurfaceReference);
    mInputSurface = new InputSurface(inputSurfaceReference.get());
    mInputSurface.makeCurrent();
    // Create a MediaCodec for the decoder, based on the extractor's format.
    mOutputSurface = new OutputSurface();

    mOutputSurface.changeFragmentShader(createFragmentShader(
            inputVideoFormat.getInteger(MediaFormat.KEY_WIDTH), inputVideoFormat.getInteger(MediaFormat.KEY_HEIGHT),
            outputWidth, outputHeight));

    mVideoDecoder = createVideoDecoder(inputVideoFormat, mOutputSurface.getSurface());

    mVideoDecoderInputBuffers = mVideoDecoder.getInputBuffers();
    mVideoEncoderOutputBuffers = mVideoEncoder.getOutputBuffers();
    mVideoDecoderOutputBufferInfo = new MediaCodec.BufferInfo();
    mVideoEncoderOutputBufferInfo = new MediaCodec.BufferInfo();

    if (mTimeFrom > 0) {
        mVideoExtractor.seekTo(mTimeFrom * 1000, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
        Log.i(TAG, "Seek video:" + mTimeFrom + " " + mVideoExtractor.getSampleTime());
    }
}
 
Example 12
Source File: AudioTrackConverter.java    From mollyim-android with GNU General Public License v3.0 4 votes vote down vote up
private AudioTrackConverter(
        final @NonNull MediaExtractor audioExtractor,
        final int audioInputTrack,
        long timeFrom,
        long timeTo,
        int audioBitrate) throws IOException {

    mTimeFrom = timeFrom;
    mTimeTo = timeTo;
    mAudioExtractor = audioExtractor;
    mAudioBitrate = audioBitrate;

    final MediaCodecInfo audioCodecInfo = MediaConverter.selectCodec(OUTPUT_AUDIO_MIME_TYPE);
    if (audioCodecInfo == null) {
        // Don't fail CTS if they don't have an AAC codec (not here, anyway).
        Log.e(TAG, "Unable to find an appropriate codec for " + OUTPUT_AUDIO_MIME_TYPE);
        throw new FileNotFoundException();
    }
    if (VERBOSE) Log.d(TAG, "audio found codec: " + audioCodecInfo.getName());

    final MediaFormat inputAudioFormat = mAudioExtractor.getTrackFormat(audioInputTrack);
    mInputDuration = inputAudioFormat.containsKey(MediaFormat.KEY_DURATION) ? inputAudioFormat.getLong(MediaFormat.KEY_DURATION) : 0;

    final MediaFormat outputAudioFormat =
            MediaFormat.createAudioFormat(
                    OUTPUT_AUDIO_MIME_TYPE,
                    inputAudioFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE),
                    inputAudioFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
    outputAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, audioBitrate);
    outputAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, OUTPUT_AUDIO_AAC_PROFILE);
    outputAudioFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 16 * 1024);

    // Create a MediaCodec for the desired codec, then configure it as an encoder with
    // our desired properties. Request a Surface to use for input.
    mAudioEncoder = createAudioEncoder(audioCodecInfo, outputAudioFormat);
    // Create a MediaCodec for the decoder, based on the extractor's format.
    mAudioDecoder = createAudioDecoder(inputAudioFormat);

    mAudioDecoderInputBuffers = mAudioDecoder.getInputBuffers();
    mAudioDecoderOutputBuffers = mAudioDecoder.getOutputBuffers();
    mAudioEncoderInputBuffers = mAudioEncoder.getInputBuffers();
    mAudioEncoderOutputBuffers = mAudioEncoder.getOutputBuffers();
    mAudioDecoderOutputBufferInfo = new MediaCodec.BufferInfo();
    mAudioEncoderOutputBufferInfo = new MediaCodec.BufferInfo();

    if (mTimeFrom > 0) {
        mAudioExtractor.seekTo(mTimeFrom * 1000, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
        Log.i(TAG, "Seek audio:" + mTimeFrom + " " + mAudioExtractor.getSampleTime());
    }
}
 
Example 13
Source File: BaseTransformationFragment.java    From LiTr with BSD 2-Clause "Simplified" License 4 votes vote down vote up
private long getLong(@NonNull MediaFormat mediaFormat, @NonNull String key) {
    if (mediaFormat.containsKey(key)) {
        return mediaFormat.getLong(key);
    }
    return -1;
}
 
Example 14
Source File: AudioUtil.java    From VideoProcessor with Apache License 2.0 4 votes vote down vote up
/**
 * 不需要改变音频速率的情况下,直接读写就可
 */
public static long writeAudioTrack(MediaExtractor extractor, MediaMuxer mediaMuxer, int muxerAudioTrackIndex,
                                   Integer startTimeUs, Integer endTimeUs, long baseMuxerFrameTimeUs, VideoProgressListener listener) throws IOException {
    int audioTrack = VideoUtil.selectTrack(extractor, true);
    extractor.selectTrack(audioTrack);
    if (startTimeUs == null) {
        startTimeUs = 0;
    }
    extractor.seekTo(startTimeUs, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
    MediaFormat audioFormat = extractor.getTrackFormat(audioTrack);
    long durationUs = audioFormat.getLong(MediaFormat.KEY_DURATION);
    int maxBufferSize = audioFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
    ByteBuffer buffer = ByteBuffer.allocateDirect(maxBufferSize);
    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();

    long lastFrametimeUs = baseMuxerFrameTimeUs;
    while (true) {
        long sampleTimeUs = extractor.getSampleTime();
        if (sampleTimeUs == -1) {
            break;
        }
        if (sampleTimeUs < startTimeUs) {
            extractor.advance();
            continue;
        }
        if (endTimeUs != null && sampleTimeUs > endTimeUs) {
            break;
        }
        if (listener != null) {
            float progress = (sampleTimeUs - startTimeUs) / (float) (endTimeUs == null ? durationUs : endTimeUs - startTimeUs);
            progress = progress < 0 ? 0 : progress;
            progress = progress > 1 ? 1 : progress;
            listener.onProgress(progress);
        }
        info.presentationTimeUs = sampleTimeUs - startTimeUs + baseMuxerFrameTimeUs;
        info.flags = extractor.getSampleFlags();
        info.size = extractor.readSampleData(buffer, 0);
        if (info.size < 0) {
            break;
        }
        CL.i("writeAudioSampleData,time:" + info.presentationTimeUs / 1000f);
        mediaMuxer.writeSampleData(muxerAudioTrackIndex, buffer, info);
        lastFrametimeUs = info.presentationTimeUs;
        extractor.advance();
    }
    return lastFrametimeUs;
}