ffmpeg
비디오 파일의 하위 폴더가 포함된 폴더를 읽고 HEVC로 인코딩되지 않은 파일을 선택하여 전달한 다음 입력과 출력 파일을 비교하는 간단한(몇 가지 명령만 실행) 스크립트를 얻으려고 합니다. 출력 크기가 더 크면 다음 파일로 이동하고, 크기가 더 작으면 원본 파일을 교체합니다.
내 논리는 이렇습니다.
순수 txt 목록을 준비합니다.
find /folder -type f \( -iname "*.mkv" -o -iname "*.mp4" -o -iname "*.avi" \) > log.txt
txt를 다음으로 전달하세요.
ffprobe
ffprobe "log.txt" -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1
여기 ffprobe
에서 행 1,2,3 등이 에서 수신되어야 하지만 단일 입력만 허용되므로 log.txt
이를 수행하는 방법을 모르겠습니다 .ffprobe
ffprobe
목록을 실행하고 HEVC가 아닌 결과를 출력해야 합니다.log1.txt
트랜스코딩을 위해 시스템 폴더를 전달
log1.txt
해야 하는 위치 입니다 . 작업 명령이 있는데 여기 구문은 단일 파일에 문제가 되지 않습니다.ffmpeg
/tmp
ffmpeg
입력과 출력을 비교합니다. 입력이 출력보다 크면 교체합니다. 출력이 입력보다 크면 이를 버리고 다음으로 넘어갑니다.
내가 겪고 있는 문제는 주로 변수 전달(2. 참조) 및 명시적 전달(5.)과 관련이 있습니다. 해결책이 아닌 위의 문제를 처리하는 방법에 대한 몇 가지 지침이 필요합니다.
읽어 주셔서 감사합니다.
답변1
파일 목록을 생성하기 위해 find를 사용해서는 안 됩니다.find 출력을 구문 분석하는 것은 위험하므로 피해야 합니다.– 특히 공백이 포함된 파일 이름의 경우. 대부분의 작업을 수행하는 스크립트를 준비하고 find의 exec 인수를 통해 실행하는 것이 더 좋습니다(보호된 세미콜론이 필요하며 bash가 find 대신 와일드카드를 확장하는 것을 방지하기 위해 작은따옴표도 사용합니다).
find /folder -type f \( -iname '*.mkv' -o -iname '*.mp4' -o -iname '*.avi' \) -exec transcode.sh {} \;
파일에서 직접 ffprobe를 호출하고 출력을 grep으로 파이프하여 코덱 이름을 확인할 수 있습니다(원하는 코덱의 실제 이름을 알지 못하므로 조정하시기 바랍니다).
if ffprobe "$1" -hide_banner -loglevel panic -select_streams v:0 -show_entries stream=codec_name | grep -q 'hvec'
then
# TODO: do transcoding
fi
트랜스코딩 후 다음을 수행할 수 있습니다.파일 크기 비교그리고 그에 따라 행동하십시오(다음에 스크립트를 실행할 때 파일을 다시 트랜스코딩하는 데 시간과 노력을 낭비하지 않도록 의도적으로 파일 스텁을 그대로 두었습니다).
if [[ $(stat -c%s "$f") -gt $(stat -c%s "$fhvec") ]]
then
mv "$fhvec" "$f"
else
truncate -s 0 "$fhvec"
fi
보다 일반적인 경고: 중요하지 않은 데이터(미리보기, 썸네일, 프록시)에 대해서만 이 작업을 수행하세요. HVEC는 강력한 인코더이지만 두 가지 다른 인코더의 압축 아티팩트가 포함된 비디오가 나올 수도 있습니다. 그들은 작을 수도 있지만 보기에도 흉해 보입니다.