Skip to content

Instantly share code, notes, and snippets.

@paul-chambers
Last active April 16, 2024 12:49
Show Gist options
  • Save paul-chambers/969b6f7d29a5fc8efaf1fb7ea1a2c9a3 to your computer and use it in GitHub Desktop.
Save paul-chambers/969b6f7d29a5fc8efaf1fb7ea1a2c9a3 to your computer and use it in GitHub Desktop.
A little ffmpeg magic to remove those annoying black bars that studios insist on encoding into the media.
#!/bin/bash
# a script that uses ffmpeg to detect the 'black bars' that are sometimes encoded into the video and then
# reencodes the video stream (only) to remove them and restore the content's original aspect ratio.
# if the original video codec used was MPEG2 or h264, it also re-encodes it to libx264.
input="${1}"
output="${input%.*}.crop.${input##*.}"
# scan 5 seconds of video, starting one minute in, to autodetect the cropping dimensions to use
crop=$( ffmpeg -nostats -i "${input}" -ss 60 -t 5 -vf "cropdetect=24:16:0" -f null - 2>&1 \
| tail -3 \
| sed -n -e 's/^.* \(crop=[0-9:]*\)$/\1/ p' )
echo "${crop}"
codec=$( ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "${input}" )
case ${codec} in
mpeg2video)
codec=libx264
echo "converting mpeg2 to libx264"
;;
h264)
codec=libx264
echo "converting h264 to libx264"
;;
*)
echo "original codec is ${codec}"
esac
ffmpeg -i "${input}" -map 0 -c copy -c:v ${codec} -crf 17 -filter:v "${crop}" "${output}"
@f1-outsourcing
Copy link

Yes I read yesterday the man pages, should have done this earlier ;) With this cropdetect=24:2:0 I got the accurate values, but probably better indeed to stick to 16.

I also wondered why you did the re-encoding, I am trying to use something like this, but it does not seem to work with vlc 3

mkvpropedit test.mkv --edit track:v1 --set pixel-crop-top=138 --set pixel-crop-bottom=138

Did you decide to re encode because such things are not working? I also read something that cropping could be set with h264info tool, which should also not require re-enconding.

@f1-outsourcing
Copy link

This could be interesting to alter in your script, I found this. I use the uniq -c quite often, and split the values into the bash array like this.
| grep -o crop=.* | sort | uniq -c | sort -n | tail -1 | grep -o "[0-9]*:[0-9]*:[0-9]*:[0-9]*"

@paul-chambers
Copy link
Author

I've found that few (no?) players honor the (advisory) mkv-specific crop parameters. At least none of the ones I care about. To avoid re-encoding the video stream, I'd have to write some fiendish code to remove black macroblocks at the edge of I-frames, and adjust co-ordinates of the B & P frames in a GOP. Honestly, there's a good reason no-one's done it already - it's both hard to get right and highly codec-specific. Modern encoders at pretty darn good if you're not too stingy with bitrates, so re-encoding does little harm. Just takes time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment