모든 자막을 그대로 유지하면서 공간을 절약하기 위해 ffmpeg를 사용하여 Matroska 파일의 비디오 스트림을 다시 인코딩하려고 합니다. 정확한 스트림 번호를 지정하지 않고도 작동하는 일반 명령을 작성하고 싶습니다. 이제 ffmpeg에서 기본 비디오 스트림과 기본 오디오 스트림을 선택한 다음 모든 자막을 선택하는 방법을 모르겠습니다.
현재 사용 중인 입력 파일에는 이러한 스트림이 있지만 다른 파일에는 다른 스트림이 있습니다.
[lavf] stream 0: video (mpeg2video), -vid 0
[lavf] stream 1: audio (ac3), -aid 0, -alang eng, Surround 5.1
[lavf] stream 2: audio (ac3), -aid 1, -alang fre, Surround 5.1
[lavf] stream 3: audio (ac3), -aid 2, -alang ita, Surround 5.1
[lavf] stream 4: audio (ac3), -aid 3, -alang spa, Surround 5.1
[lavf] stream 5: audio (ac3), -aid 4, -alang eng, Stereo
[lavf] stream 6: subtitle (dvdsub), -sid 0, -slang eng
[lavf] stream 7: subtitle (dvdsub), -sid 1, -slang fre
[lavf] stream 8: subtitle (dvdsub), -sid 2, -slang ita
[lavf] stream 9: subtitle (dvdsub), -sid 3, -slang spa
[lavf] stream 10: subtitle (dvdsub), -sid 4, -slang ara
[lavf] stream 11: subtitle (dvdsub), -sid 5, -slang dan
[lavf] stream 12: subtitle (dvdsub), -sid 6, -slang dut
[lavf] stream 13: subtitle (dvdsub), -sid 7, -slang fin
[lavf] stream 14: subtitle (dvdsub), -sid 8, -slang ice
[lavf] stream 15: subtitle (dvdsub), -sid 9, -slang nor
[lavf] stream 16: subtitle (dvdsub), -sid 10, -slang por
[lavf] stream 17: subtitle (dvdsub), -sid 11, -slang swe
[lavf] stream 18: subtitle (dvdsub), -sid 12, -slang fre
[lavf] stream 19: subtitle (dvdsub), -sid 13, -slang ita
[lavf] stream 20: subtitle (dvdsub), -sid 14, -slang spa
내가 시도한 명령:
ffmpeg -i IN.mkv -c:v libx264 -threads 4 -speed 1 -f matroska OUT.mkv
결과: 비디오 스트림 1개, 오디오 스트림 1개,자막 스트리밍 없음.
ffmpeg -i IN.mkv -c:v libx264 -threads 4 -speed 1 -f matroska -c:s copy OUT.mkv
결과: 비디오 스트림 1개, 오디오 스트림 1개,자막 스트림.
ffmpeg -i IN.mkv -c:v libx264 -threads 4 -speed 1 -f matroska -map 0 OUT.mkv
결과:모든 동영상,모든 오디오, 모든 자막.
ffmpeg -i IN.mkv -c:v libx264 -threads 4 -speed 1 -f matroska -c:s copy -map 0:s OUT.mkv
결과:영상 없음,오디오 없음, 모든 자막.
매뉴얼에서 알 수 있듯이 -c:s copy
기본 스트림뿐만 아니라 모든 스트림을 복사해야 하는데 그렇지 않습니다. 어쩌면 이것은 버그일까요?
명확히하기 위해 내가 추구하는 결과는 다음과 같습니다.이푸아이디어,하나오디오 및모두부제.
답변1
이것스트림 선택 기본 동작은 각 스트림 유형에 대해 하나의 스트림만 선택합니다., 따라서 여러 오디오 스트림이 있는 입력은 하나의 오디오 스트림으로 출력을 생성합니다. 이 동작을 비활성화하고 원하는 스트림을 수동으로 선택하려면 다음을 사용하십시오.-map
옵션.
이 예 -c copy
는스트림 복사(재다중화) 입력에서 출력으로. 녹음이 발생하지 않습니다.
스트림 모든 스트림 복사
ffmpeg -i input -map 0 -c copy output
첫 번째 비디오 스트림, 두 번째 오디오 스트림, 모든 자막
ffmpeg -i input -map 0:v:0 -map 0:a:1 -map 0:s -c copy output
세 번째 비디오 스트림, 모든 오디오 스트림, 자막 없음
이 예제에서는네거티브 매핑자막을 제외합니다.
ffmpeg -i input -map 0:v:2 -map 0:a -map -0:s -c copy output
여러 입력에서 스트림 선택
모든 비디오는 입력 0에서 나오고 모든 오디오는 입력 1에서 나옵니다.
ffmpeg -i input0 -i input1 -map 0:v -map 1:a -c copy output
답변2
#!/bin/bash # 주어진 디렉토리의 각 MKV 파일에서 이전 형식의 비디오 트랙을 추출하고 이를 x265로 트랜스코딩합니다. # 목적에 맞게 확장 가능 ;-) 저는 이 스크립트를 1년 넘게 실행해 왔습니다. 에코 MKV: 마이그레이션 echo "| 인수 없음: 후보 디렉터리 트리 검색" echo "| dir : 이 디렉토리를 스캔하세요" echo "| . -c : 이 후보의 비디오 트랙을 H.265(x265)로 변환합니다." echo "| .-c -r : 새로운 결과 비디오로 변환 및 리믹스" echo "\ . -c -r -k : 중간 비디오 파일을 유지합니다(기본값은 아님)" 에코"" 날짜 echo는 MKV 파일의 모든 디렉터리를 읽고 Mpeg-4p2, H264, XVid, DivX 또는 H263 트랙이 있는지 확인합니다. echo가 있으면 mkvextract로 추출하고 ffmpeg로 H265로 변환합니다. echo 리믹스하는 경우 원본 파일의 이름은 .old.mkv로 지정되고 새 파일은 접미사 .x265.mkv가 붙은 원본 파일 이름을 유지합니다. echo mkvmerge를 사용하여 리믹스하면 새 비디오 트랙이 통합되지만 원래의 이전 형식 트랙은 통합되지 않습니다. echo "(참조: ffmpeg bla bla bla -d \!0 trackno 트랙 0이 오래된 비디오 형식인 경우 -d로 건너뜁니다.)" 에코. vidxt="mp4" 비디오코="libx265" H264="" H264="(H.264)|H264|(MPEG-4p10)|" CRF="25" VIDRATE="1500k" #코어가 4개라면 400% 가능합니다. 프로세스를 65%로 제한하십시오. CPULIM=240 #SCALE="-vf 규모=1280:720" #RATE="-r 23.976216" # 디렉터리가 지정되지 않은 경우 로컬 디렉터리에서 작업합니다. if["$1"==""]; 디렉토리="." 로 변환하다 "" 도레먹스="" 계속="" 기타 디렉터리="$1" 전환=$2 doremux=$3 예치금=$4 필리핀 제도 # 정말 오래된 형식을 제거하기 위해 먼저 이 스크립트를 실행합니다... if [ "$H264" == " " ]; echo "H.264 비디오 트랙을 스캔하지 마세요." 기타 echo "H.264 비디오 트랙을 동시에 스캔:"$H264 필리핀 제도 # 이 디렉토리와 하위 디렉토리에 있는 모든 MKV 파일을 가져옵니다. 파일 이름을 읽을 때 "$DIR" -type f-name '*.mkv' 찾기 | 하다 # 어떤 트랙에 자막이 포함되어 있는지 알아보세요 # 에코 확인: $filename 홈=0 mkvmerge -i "$filename" | 하위 줄을 읽을 때 'video' | 하다 후보=`echo $subline | egrep -o $H264"(avc1)|(XVID)|(DX50)|MPEG-4p2"` #echo $filename.$subline if [ "$candidate" != "" ]; # Grep 비디오/오디오 트랙 번호 tracknumber=`echo $subline | egrep -o "[0-9]{1,2}" |egrep -o "[0-9]{1,2}" |head-1` #echo " EVAL : " $candidate " trk: " $tracknumber " cand: " $cand if [ $cand != 1 ]; 에코 "|" echo $filename" : " $subline " : " $tracknumber MYDAT=$(ls -l --full-time "${filename}" |gawk -F ' ' '{ 인쇄 $6" "$7 }' | gawk -F. '{ 인쇄 $1 }') echo " | 원래 날짜: "$MYDAT 홈=1 기타 echo "/--다음 노래" 필리핀 제도 에코 "|" `날짜` echo " | 후보자: [$candidate]" # 자막의 기본 이름을 가져옵니다. 기본 파일 이름=${파일 이름%.*} echo " \-- 비디오: "$subline" ($basefilename)" if["$doconvert"=="-c"]; # 트랙을 .tmp 파일로 추출 echo " -- $tracknumber:$basefilename.vid.tmp 추출(평균 2분) " `mkvextract 트랙 "$filename" $tracknumber:"$basefilename.vid.tmp" >>/dev/null 2>&1` `chmod g+rw "$basefilename.vid.tmp"` # FFMPEG 변환 수행 에코 "--" `날짜` echo " -- FFMpeg는 $vidco를 통해 $basefilename.vid.tmp를 $vidxt로 변환합니다(평균 2시간)" # echo ` ffmpeg -i "$basefilename.vid.tmp" $RATE -c:v:0 $vidco -crf $CRF -b:v:0 $VIDRATE $SCALE "$basefilename.$tracknumber.$vidxt"` > /dev/null 2>&1 `cpulimit -f --limit=$CPULIM -- ffmpeg -i "$basefilename.vid.tmp" $RATE -c:v:0 $vidco -crf $CRF -b:v:0 $VIDRATE $SCALE "$basefilename .$tracknumber.$vidxt" >/dev/null 2>&1` if["$keep"==""]; `rm "$basefilename.vid.tmp" >/dev/null 2>&1` 필리핀 제도 if [ "$doremux" == "-r" ]; 에코 "--" `날짜` `mv "$filename" "$basefilename".old.mkv >/dev/null 2>&1` echo " -- $tracknumber 트랙 없이 $filename을 $vidxt와 믹스합니다. (평균 4분)" mkvmerge -o "$basefilename.x265.mkv" -d \!$tracknumber "$basefilename.old.mkv" "$basefilename.$tracknumber.$vidxt" >>/dev/null 2>&1 if["$keep"==""]; `rm "$basefilename.$tracknumber.$vidxt" >/dev/null 2>&1` 필리핀 제도 touch --date="$MYDAT" "$basefilename.x265.mkv" >>/dev/null 2>&1 필리핀 제도 필리핀 제도 필리핀 제도 완벽한 완벽한