Zulko / moviepy

Video editing with Python
https://zulko.github.io/moviepy/
MIT License
12.39k stars 1.55k forks source link

Clip does not preserve aspect ratio metadata: SAR and DAR - and suggested workaround #611

Open pkarp0 opened 7 years ago

pkarp0 commented 7 years ago

An original video 1080x1080 file includes SAR (sample_aspect_ratio) that is used by video players to scale the video. In this example SAR = 4:3

ffprobe version 3.0.1 Copyright (c) 2007-2016 the FFmpeg developers
  built with Apple LLVM version 7.3.0 (clang-703.0.31)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.0.1 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libxvid --enable-libvorbis --enable-libvpx --enable-vda
  libavutil      55. 17.103 / 55. 17.103
  libavcodec     57. 24.102 / 57. 24.102
  libavformat    57. 25.100 / 57. 25.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 31.100 /  6. 31.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
[h264 @ 0x7fede4008600] Increasing reorder buffer to 1
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/peterkarp/Downloads/NOT_IN_MY_NAME_FINAL_CUT.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42mp41
    creation_time   : 2017-06-29 13:28:20
  Duration: 00:01:28.75, start: 0.000000, bitrate: 10934 kb/s
    Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1080x1080 [SAR 4:3 DAR 4:3], 10618 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Metadata:
      creation_time   : 2017-06-29 13:28:21
      handler_name    : Alias Data Handler
      encoder         : AVC Coding
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 317 kb/s (default)
    Metadata:
      creation_time   : 2017-06-29 13:28:21
      handler_name    : Alias Data Handler

After loading the VideoFileClip and writing it the SAR information is missing and the video is displayed incorrectly 1:1.

ffprobe version 3.0.1 Copyright (c) 2007-2016 the FFmpeg developers
  built with Apple LLVM version 7.3.0 (clang-703.0.31)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.0.1 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libxvid --enable-libvorbis --enable-libvpx --enable-vda
  libavutil      55. 17.103 / 55. 17.103
  libavcodec     57. 24.102 / 57. 24.102
  libavformat    57. 25.100 / 57. 25.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 31.100 /  6. 31.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'aaa_output.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.25.100
  Duration: 00:00:04.05, start: 0.025057, bitrate: 9337 kb/s
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1080x1080, 9307 kb/s, 23.98 fps, 23.98 tbr, 19184 tbn, 47.96 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: mp3 (mp4a / 0x6134706D), 44100 Hz, stereo, s16p, 127 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
pkarp0 commented 7 years ago

Because there are videos that are sized at display time I suggest adding this code block to ffmpeg_parse_infos to gather the SAR and DAR information along with the width and height. This will allow a user to get the SAR so the video can be resized if needed.

            # get the size, of the form 460x320 (w x h)
            match = re.search(" [0-9]*x[0-9]*(,| )", line)
            s = list(map(int, line[match.start():match.end()-1].split('x')))
            result['video_size'] = s
>>> Insert the following code:
            # Get the SAR and DAR aspect ratios of the form 4:3
            match = re.search(" \[SAR (?P<sar_w>\d+):(?P<sar_h>\d+) DAR (?P<dar_w>\d+):(?P<dar_h>\d+)\]", line)
            if match:
                ar_dict = {'video_sar': ['sar_w', 'sar_h'],
                           'video_dar': ['dar_w', 'dar_h']}
                for k, v in ar_dict.items():
                    result[k] = [int(match.groupdict()[item]) for item in v]

The following can be included in the FFMPEG_VideoReader constructor:

    self.sar = infos.get('video_sar')
    self.dar = infos.get('video_dar')
tburrows13 commented 4 years ago

Linking #289