0

MediaProjection API로 화면을 녹화하려고합니다. 미디어 프로젝션으로 녹화 된 비디오를 자르고 싶습니다. 타사 종속성을 사용하지 않고이를 수행 할 수있는 방법이 있습니까?MediaCodec으로 비디오 다듬기 방법

+0

발견? –

+0

MediaProjection Session의 출력은 무엇인지 모르지만 MediaCodec을 사용하는 것이 좋습니다. 여행은 여기에서 시작됩니다 : https://stackoverflow.com/questions/20468211/use-mediacodec-and-mediaextractor-to-decode-and-code-video –

+0

@martynmlostekk 예, 찾았습니다. 나는 대답으로 게시 할 것입니다 – vezikon

답변

1

파고를 많이 후, 난 당신이 해결책을 찾기 않은이 조각

/** 
* @param srcPath the path of source video file. 
* @param dstPath the path of destination video file. 
* @param startMs starting time in milliseconds for trimming. Set to 
*     negative if starting from beginning. 
* @param endMs end time for trimming in milliseconds. Set to negative if 
*     no trimming at the end. 
* @param useAudio true if keep the audio track from the source. 
* @param useVideo true if keep the video track from the source. 
* @throws IOException 
*/ 
@TargetApi(Build.VERSION_CODES.LOLLIPOP) 
private static void genVideoUsingMuxer(String srcPath, String dstPath, 
             int startMs, int endMs, boolean useAudio, boolean 
                useVideo) 
     throws IOException { 
    // Set up MediaExtractor to read from the source. 
    MediaExtractor extractor = new MediaExtractor(); 
    extractor.setDataSource(srcPath); 
    int trackCount = extractor.getTrackCount(); 
    // Set up MediaMuxer for the destination. 
    MediaMuxer muxer; 
    muxer = new MediaMuxer(dstPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); 
    // Set up the tracks and retrieve the max buffer size for selected 
    // tracks. 
    HashMap<Integer, Integer> indexMap = new HashMap<>(trackCount); 
    int bufferSize = -1; 
    for (int i = 0; i < trackCount; i++) { 
     MediaFormat format = extractor.getTrackFormat(i); 
     String mime = format.getString(MediaFormat.KEY_MIME); 
     boolean selectCurrentTrack = false; 
     if (mime.startsWith("audio/") && useAudio) { 
      selectCurrentTrack = true; 
     } else if (mime.startsWith("video/") && useVideo) { 
      selectCurrentTrack = true; 
     } 
     if (selectCurrentTrack) { 
      extractor.selectTrack(i); 
      int dstIndex = muxer.addTrack(format); 
      indexMap.put(i, dstIndex); 
      if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) { 
       int newSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE); 
       bufferSize = newSize > bufferSize ? newSize : bufferSize; 
      } 
     } 
    } 
    if (bufferSize < 0) { 
     bufferSize = DEFAULT_BUFFER_SIZE; 
    } 
    // Set up the orientation and starting time for extractor. 
    MediaMetadataRetriever retrieverSrc = new MediaMetadataRetriever(); 
    retrieverSrc.setDataSource(srcPath); 
    String degreesString = retrieverSrc.extractMetadata(
      MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION); 
    if (degreesString != null) { 
     int degrees = Integer.parseInt(degreesString); 
     if (degrees >= 0) { 
      muxer.setOrientationHint(degrees); 
     } 
    } 
    if (startMs > 0) { 
     extractor.seekTo(startMs * 1000, MediaExtractor.SEEK_TO_CLOSEST_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. 
    int offset = 0; 
    int trackIndex = -1; 
    ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize); 
    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); 
    try { 
     muxer.start(); 
     while (true) { 
      bufferInfo.offset = offset; 
      bufferInfo.size = extractor.readSampleData(dstBuf, offset); 
      if (bufferInfo.size < 0) { 
       InstabugSDKLogger.d(TAG, "Saw input EOS."); 
       bufferInfo.size = 0; 
       break; 
      } else { 
       bufferInfo.presentationTimeUs = extractor.getSampleTime(); 
       if (endMs > 0 && bufferInfo.presentationTimeUs > (endMs * 1000)) { 
        InstabugSDKLogger.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(); 

     //deleting the old file 
     File file = new File(srcPath); 
     file.delete(); 
    } catch (IllegalStateException e) { 
     // Swallow the exception due to malformed source. 
     InstabugSDKLogger.w(TAG, "The source video file is malformed"); 
    } finally { 
     muxer.release(); 
    } 
    return; 
} 
+0

이 스 니펫을 기반으로, 키 프레임으로만 트리밍됩니다. 그렇지 않습니까? 멀티플렉서에 키 프레임 이후 샘플 데이터를 공급하여 B 프레임에서 시작할 수 있습니까? –