/** * Creates a new clipping source that wraps the specified source and provides samples between the * specified start and end position. * * @param mediaSource The single-period source to wrap. * @param startPositionUs The start position within {@code mediaSource}'s window at which to start * providing samples, in microseconds. * @param endPositionUs The end position within {@code mediaSource}'s window at which to stop * providing samples, in microseconds. Specify {@link C#TIME_END_OF_SOURCE} to provide samples * from the specified start point up to the end of the source. Specifying a position that * exceeds the {@code mediaSource}'s duration will also result in the end of the source not * being clipped. */ publicClippingMediaSource(MediaSource mediaSource, long startPositionUs, long endPositionUs) { this( mediaSource, startPositionUs, endPositionUs, /* enableInitialDiscontinuity= */true, /* allowDynamicClippingUpdates= */false, /* relativeToDefaultPosition= */false); }
/** * @param mediaSources The {@link MediaSource}s to concatenate. It is valid for the same {@link * MediaSource} instance to be present more than once in the array. */ publicConcatenatingMediaSource(MediaSource... mediaSources) { this(/* isAtomic= */false, mediaSources); }
视频变速:
变速使用setPlaybackParameters设置速度参数
1 2 3 4
SimpleExoPlayersimpleExoPlayer= player.getExoPlayer(); if (simpleExoPlayer != null) { simpleExoPlayer.setPlaybackParameters(newPlaybackParameters(speed)); }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) publicstaticbooleangenVideoUsingMuxer(Context context, String srcPath, String dstPath, int startMs, int endMs, boolean useAudio, boolean useVideo)throws IOException { booleansuccess=true; // Set up MediaExtractor to read from the source. MediaExtractorextractor=newMediaExtractor(); extractor.setDataSource(srcPath); inttrackCount= extractor.getTrackCount(); // Set up MediaMuxer for the destination. MediaMuxer muxer; muxer = newMediaMuxer(dstPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); // Set up the tracks and retrieve the max buffer size for selected tracks. HashMap<Integer, Integer> indexMap = newHashMap<>(trackCount); intbufferSize= -1; for (inti=0; i < trackCount; i++) { MediaFormatformat= extractor.getTrackFormat(i); Stringmime= format.getString(MediaFormat.KEY_MIME); booleanselectCurrentTrack=false; if (mime.startsWith("audio/") && useAudio) { selectCurrentTrack = true; } elseif (mime.startsWith("video/") && useVideo) { selectCurrentTrack = true; } if (selectCurrentTrack) { extractor.selectTrack(i); intdstIndex= muxer.addTrack(format); indexMap.put(i, dstIndex); if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) { intnewSize= format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE); bufferSize = newSize > bufferSize ? newSize : bufferSize; } } } if (bufferSize < 0) { bufferSize = 1080*1920*30; } // Set up the orientation and starting time for extractor. MediaMetadataRetrieverretrieverSrc=newMediaMetadataRetriever(); retrieverSrc.setDataSource(srcPath); StringdegreesString= retrieverSrc.extractMetadata( MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION); if (degreesString != null) { intdegrees= Integer.parseInt(degreesString); if (degrees >= 0) { muxer.setOrientationHint(degrees); } } if (startMs > 0) { extractor.seekTo(startMs * 1000, MediaExtractor.SEEK_TO_PREVIOUS_SYNC); } // Copy the samples from MediaExtractor to MediaMuxer. We will loop // for copying each sample and stop when we get to the end of the source // file or exceed the end time of the trimming. intoffset=0; inttrackIndex= -1; ByteBufferdstBuf= ByteBuffer.allocate(bufferSize); MediaCodec.BufferInfobufferInfo=newMediaCodec.BufferInfo(); try { muxer.start(); while (true) { bufferInfo.offset = offset; bufferInfo.size = extractor.readSampleData(dstBuf, offset); if (bufferInfo.size < 0) { Log.d(TAG, "Saw input EOS."); bufferInfo.size = 0; break; } else { bufferInfo.presentationTimeUs = extractor.getSampleTime(); if (endMs > 0 && bufferInfo.presentationTimeUs > (endMs * 1000)) { Log.d(TAG, "The current sample is over the trim end time."); break; } else { bufferInfo.flags = extractor.getSampleFlags(); trackIndex = extractor.getSampleTrackIndex(); muxer.writeSampleData(indexMap.get(trackIndex), dstBuf, bufferInfo); extractor.advance(); } } } muxer.stop(); } catch (Exception e) { // Swallow the exception due to malformed source. Log.w(TAG, "The source video file is malformed"); success = false; } finally { muxer.release(); } return success; }