내 요구 사항은 정확히 (몇 프레임 위로 / 아래로) 플라이 MP4 (h264 + aac) https 비디오 스트림을 잘라내는 것입니다. 휴대 전화에서 ffmpeg를 가장 빨리 할 수 있습니다 - 필요한 경우 나쁜 압축 (더 큰 출력 파일) 더 큰 절단 속도. 현재이 명령으로 비디오를 자르고 있습니다 :
ffmpeg -ss [start_time] -i https://domain/in.mp4 -t 00:00:10.000 -c:a copy -c:v copy out.mp4
이 방법 (비트 스트림 복사)은 매우 빠르며 (10 초 길이의 비디오를 잘 처리 할 수있는 좋은 네트워크에서는 1 초 미만) 비디오를 정확하게 자르지 않습니다. 비디오는 부정확 한 키 프레임에서 잘려나갑니다.
그래서 내 생각은 비디오 프레임을 재생하기 전에 동영상에서이 부정확성 (키 프레임으로부터의 거리)을 보상하는 것입니다.
delta = start_time - first_key_frame_timestamp_before_start_time
델타를 계산하려면 시작 시간 전에 첫 번째 키 프레임의 타임 스탬프를 얻는 매우 빠른 방법이 필요합니다. 나는 본 적이 우편 start_time 이전에 첫 번째 키 프레임의 타임 스탬프를 얻는 방법에 대해 설명하지만이 방법은 비디오의 중간이라고 할 수있는이 작업이 오래 걸리기 때문에 오랜 (2 시간 +) 비디오에는 실용적이지 않습니다. 나는 이런 것을 필요로 할 것이다 :
ffmpeg -ss 01:30:06.000 -i https://domain/in.mp4 -t 2 -show_frames > frame_meta.txt
또한 다음 명령을 사용하여 비디오를 다시 인코딩 (2 시간 길이의 비디오, 비디오 중간에 10 초 길이의 비디오 잘라 내기)하여 정확한 절단을 시도했습니다.
ffmpeg -ss [start_time] -i https://domain/in.mp4 -t 10 out.mp4
그러나 두 번째 비트 스트림 복사 명령보다 짧아서 모바일에서 길게 (~ 16 초) 걸립니다. 유용한 힌트 또는 솔루션 Thx.
편집 1 :
ExoPlayer (Android 멀티미디어 플레이어) 내부 클래스를 사용하여 delta를 계산하고 start_time 이전에 첫 번째 keyFrame의 타임 스탬프를 얻었습니다.이 방법은 500ms (매우 짧은 비디오)에서 최대 1500ms (매우 긴 비디오의 경우)까지 매우 빠릅니다. 근본적으로이 방법은 원격 mp4 스트림의 meta_headers (moov 아톰)를 구문 분석하여 start_time을 자르기 전에 keyFrame의 적절한 timeStamp를 찾은 것을 기반으로합니다. 이제 새로운 문제는 비디오가 잘리는 경우 발생합니다.
ffmpeg -ss [start_time] -i https://domain/in.mp4 -t 00:00:10.000 -c:a copy -c:v copy out.mp4
편집 목록 아톰은 다음에서 이해할 수있는 메타 헤더에 추가됩니다. 이 과 이 ffmpeg bitStream copy 명령으로 수행되는 부정확 한 비디오 커팅을 보상하기 위해 플레이어에게 델타 시간 오프셋으로 재생을 시작하라고 알려주는 게시물입니다. 그러나 Android에서 사용하는 플레이어는 동영상 시작 부분부터 정상적으로 재생되기 시작하거나 오디오가 재생되는 동안 잠시 동안 일부 프레임에서 정지되어 정상적으로 재생되기 때문에 편집 목록 재생을 지원하지 않습니다.
이전에 계산 된 델타를 찾은 다음 잘라낸 비디오에서 재생을 시작하려고하면 올바른 프레임 (예 : 델타 = 1 381ms, 실제 / 작동중인 델타 = 444ms)에 위치하지 않아 정확하지 않은 절단을 보상하는 계획이 작동하지 않습니다. (. 델타를 올바르게 계산했는지 스스로 묻는다면 IsoViewer (mp4 컨테이너 아톰 파서) 및 Avidemux로 프레임을 단계별로보고 time_stamp / frame_type 값 쌍을 조사하여 mannualy ...