
가지고 있는 저장 공간을 최대로 늘렸는데 공간을 좀 더 만들고 싶습니다.
모든 파일을 mkv로 변환하고 고해상도 파일을 낮은 해상도로 축소하는 방법을 생각했습니다.
mp4를 mkv로 변환하려면
ffmpeg -i input.mp4 -vcodec copy -acodec copy output.mkv
그리고 규모를 축소하려면
ffmpeg -i input.mp4 -vf scale=$w:$h <encoding-parameters> output.mp4
하지만 단일 mp4 파일이 아닌 모든 파일을 변환해야 하고, 처리를 마친 후 입력 파일을 제거해야 하며, 지정된 해상도 이상의 파일에 대해서만 이 작업을 수행해야 합니다. 또한 종횡비를 유지하고 싶은데 이것이 그렇게 하고 있는지 모르겠습니다.
라는 도구가 있습니다.비디오 다이어트그것은 이것의 일부입니다.
이것이 내가 하고 싶은 일이다
Recursively find every file under the current directory
If the file resolution has a height equal or greater to a given height.
Convert the file to mkv if it's in another format avi, mp4, flv, etc
Downscale to a lower resolution height, keeping the aspect ratio.
어쩌면 나도 그래야 할지도 몰라프레임 속도를 낮추세요24fps로?
더 좋은 방법이 있다면 듣고 싶습니다.
답변1
시작하기 위한 스크립트는 다음과 같습니다. 필요에 맞게 이를 수정하고, 프레임 속도 등을 변경하려면 ffmpeg에 옵션을 추가하고 싶을 것입니다.
파일이 이미 .mkv인지 확인하는 조건이 있지만 실제로는 다른 작업을 수행하지 않으므로 조건은 의미가 없습니다. 귀하의 질문으로 인해 마치 귀하가 그들과 다른 일을 하고 싶어하는 것처럼 들리기 때문에 거기에 있는 것입니다. 이유는 잘 모르겠습니다. FFMPEG는 동시에 확장하고 변환할 수 있습니다.
그러나 뭔가 다른 작업을 수행하고 싶다면 조건이 참인 경우에 대한 ffmpeg 행을 다른 것으로 변경하세요.
#!/bin/bash
# set the resolution above which you want to downscale
maxwidth=1920
maxheight=1080
# set the resolution to downscale to; the width will be
# calculated to preserve aspect ratio
targetwidth=1280
# a counter for errors
errors=0
# recursively find video files; add their names to
# an array to process
mapfile -t filenames < <(find $(pwd) -type f -iregex '.*avi$\|.*mp4$\|.*m4v$\|.*flv\|.*mkv\|.*ogv\|.*webm$\|.*mov')
# loop through the array
for filename in "${filenames[@]}" ; do
# get the resolution with ffprobe
res="$(ffprobe -hide_banner -v error -select_streams v:0 -show_entries stream=width,height -print_format csv "$filename")"
# strip "stream" off "res"
res="${res#stream,}"
# parse into width and height
width="${res%,*}"
height="${res#*,}"
# compare to maxwidth/height to see if it should be
# processed
if [[ "$width" -ge "$maxwidth" ]] || [[ "$height" -ge "$maxheight" ]] ; then
# determine the output name
outputname="${filename%.*}-downscaled.mkv"
# check if output already exists; if so, skip it
if [[ -e "$outputname" ]] ; then
continue
fi
# calculate targetheight, divide by 2 multiply by 2
# to ensure it's even
targetheight="$(( ( ( (targetwidth * height) / width) / 2) * 2 ))"
# get file extension
ext="${filename##*.}"
# do something different with mkvs?
# not sure why you would though
if [[ "$ext" =~ '[Mm]{Kk][Vv]' ]] ; then
ffmpeg -i "$filename" -vf scale="$targetwidth:$targetheight" "$outputname"
exitcode="$?"
else
ffmpeg -i "$filename" -vf scale="$targetwidth:$targetheight" "$outputname"
exitcode="$?"
fi
# if conversion was a success, delete original file
if [[ "$exitcode" == 0 ]] && [[ -e "$outputname" ]] ; then
rm "$filename"
else
echo
echo "Error processing $filename" >&2
echo "Not deleted!"
let errors++
echo
fi
fi
done
# report number of errors if there were any
if [[ "$errors" == 0 ]] ; then
exit 0
fi
echo "There were $errors errors!" >&2
exit 1
그것은 다소 과잉일 수도 있고 단순화할 수 있는 방법도 있을 수 있지만 저는 그렇게 하겠습니다.