In [1]:
import subprocess

In [2]:
video = list(Video.objects.all().order_by("-created"))[0]

In [3]:
video.original


Out[3]:
<FieldFile: cast_videos/EUMDY6qETWmpJcL2oGcNzw.MOV>

In [5]:
video.poster


Out[5]:
<ImageFieldFile: None>

In [8]:
video_url = video.original.path
video._get_video_dimensions(video_url)


Out[8]:
(None, None)

In [1]:
def get_video_dimensions(video_url):
    def get_width_height(video_type, line):
        dim_col = line.split(", ")[3]
        if video_type != "h264":
            dim_col = dim_col.split(" ")[0]
        return map(int, dim_col.split("x"))
    
    ffprobe_cmd = 'ffprobe -i "{}"'.format(video_url)
    result = subprocess.check_output(
        ffprobe_cmd, shell=True, stderr=subprocess.STDOUT
    )
    lines = result.decode("utf8").split("\n")
    width, height = None, None
    video_types = ("SAR", "hevc", "h264")
    for line in lines:
        for video_type in video_types:
            if video_type in line:
                width, height = get_width_height(video_type, line)
                break
    portrait = False
    for line in lines:
        if "rotation of" in line:
            portrait = True
    if portrait:
        width, height = height, width
    return width, height

In [23]:
get_video_dimensions(video_url)


Out[23]:
(360, 480)

In [24]:
ffmpeg_output = """
ffmpeg version 4.1.1 Copyright (c) 2000-2019 the FFmpeg developers
  built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1.1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-videotoolbox --disable-libjack --disable-indev=jack --enable-libaom --enable-libsoxr
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/jochen/projects/homepage/homepage/media/cast_videos/VID_20190228_144156.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2019-02-28T13:41:56.000000Z
    location        : +51.2380+006.7902/
    location-eng    : +51.2380+006.7902/
    com.android.version: 9
  Duration: 00:00:04.06, start: 0.000000, bitrate: 21343 kb/s
    Stream #0:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 190 kb/s (default)
    Metadata:
      creation_time   : 2019-02-28T13:41:56.000000Z
      handler_name    : SoundHandle
    Stream #0:1(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt470bg/bt470bg/smpte170m), 1920x1080, 21917 kb/s, SAR 1:1 DAR 16:9, 29.88 fps, 30.13 tbr, 90k tbn, 180k tbc (default)
    Metadata:
      rotate          : 270
      creation_time   : 2019-02-28T13:41:56.000000Z
      handler_name    : VideoHandle
    Side data:
      displaymatrix: rotation of 90.00 degrees
Stream mapping:
  Stream #0:1 -> #0:0 (h264 (native) -> mjpeg (native))
Press [q] to stop, [?] for help
Output #0, image2, to '/var/folders/yq/lq6vnk9s693bp4xr5wktm1vh0000gn/T/poster_22_kvc0v.jpg':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    com.android.version: 9
    location        : +51.2380+006.7902/
    location-eng    : +51.2380+006.7902/
    encoder         : Lavf58.20.100
    Stream #0:0(eng): Video: mjpeg, yuvj420p(pc), 1080x1920 [SAR 1:1 DAR 9:16], q=2-31, 200 kb/s, 30.13 fps, 30.13 tbn, 30.13 tbc (default)
    Metadata:
      encoder         : Lavc58.35.100 mjpeg
      creation_time   : 2019-02-28T13:41:56.000000Z
      handler_name    : VideoHandle
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
      displaymatrix: rotation of -0.00 degrees
frame=    1 fps=0.0 q=6.4 Lsize=N/A time=00:00:00.03 bitrate=N/A speed=0.263x
video:97kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
"""

In [5]:
ffmpeg_output = """
ffmpeg version 4.1.1 Copyright (c) 2000-2019 the FFmpeg developers
  built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1.1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-videotoolbox --disable-libjack --disable-indev=jack --enable-libaom --enable-libsoxr
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/jochen/projects/homepage/homepage/media/cast_videos/E6B2E327-98BB-4348-8606-1E531D121BB3.MOV':
  Metadata:
    major_brand     : qt
    minor_version   : 0
    compatible_brands: qt
    creation_time   : 2019-02-28T13:55:07.000000Z
    com.apple.quicktime.location.ISO6709: +51.2382+006.7899+036.689/
    com.apple.quicktime.make: Apple
    com.apple.quicktime.model: iPhone XS
    com.apple.quicktime.software: 12.1.4
    com.apple.quicktime.creationdate: 2019-02-28T14:55:06+0100
  Duration: 00:00:03.57, start: 0.000000, bitrate: 28918 kb/s
    Stream #0:0(und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709), 3840x2160, 28726 kb/s, 29.97 fps, 29.97 tbr, 600 tbn, 600 tbc (default)
    Metadata:
      rotate          : 90
      creation_time   : 2019-02-28T13:55:07.000000Z
      handler_name    : Core Media Video
      encoder         : HEVC
    Side data:
      displaymatrix: rotation of -90.00 degrees
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 168 kb/s (default)
    Metadata:
      creation_time   : 2019-02-28T13:55:07.000000Z
      handler_name    : Core Media Audio
    Stream #0:2(und): Data: none (mebx / 0x7862656D), 0 kb/s (default)
    Metadata:
      creation_time   : 2019-02-28T13:55:07.000000Z
      handler_name    : Core Media Metadata
    Stream #0:3(und): Data: none (mebx / 0x7862656D), 0 kb/s (default)
    Metadata:
      creation_time   : 2019-02-28T13:55:07.000000Z
      handler_name    : Core Media Metadata
Stream mapping:
  Stream #0:0 -> #0:0 (hevc (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[swscaler @ 0x7fdc29801000] deprecated pixel format used, make sure you did set range correctly
Output #0, image2, to '/var/folders/yq/lq6vnk9s693bp4xr5wktm1vh0000gn/T/poster_3w_mupml.jpg':
  Metadata:
    major_brand     : qt
    minor_version   : 0
    compatible_brands: qt
    com.apple.quicktime.creationdate: 2019-02-28T14:55:06+0100
    com.apple.quicktime.location.ISO6709: +51.2382+006.7899+036.689/
    com.apple.quicktime.make: Apple
    com.apple.quicktime.model: iPhone XS
    com.apple.quicktime.software: 12.1.4
    encoder         : Lavf58.20.100
    Stream #0:0(und): Video: mjpeg, yuvj420p(pc), 2160x3840, q=2-31, 200 kb/s, 29.97 fps, 29.97 tbn, 29.97 tbc (default)
    Metadata:
      encoder         : Lavc58.35.100 mjpeg
      creation_time   : 2019-02-28T13:55:07.000000Z
      handler_name    : Core Media Video
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
      displaymatrix: rotation of -0.00 degrees
frame=    1 fps=0.0 q=8.8 Lsize=N/A time=00:00:00.03 bitrate=N/A speed=0.0517x
video:211kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
"""

In [18]:
ffmpeg_output = """
ffprobe version 4.1.3 Copyright (c) 2007-2019 the FFmpeg developers
  built with Apple LLVM version 10.0.1 (clang-1001.0.46.4)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1.3_1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/adoptopenjdk-11.0.2.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/adoptopenjdk-11.0.2.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-videotoolbox --disable-libjack --disable-indev=jack --enable-libaom --enable-libsoxr
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Michaelsbergschaukel.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 2019-04-27T00:04:26.000000Z
    title           : Michaelsbergschaukel
    date            : 2018-09-22T14:58:10+0200
    encoder         : HandBrake 1.2.1 2019021700
  Duration: 00:00:13.79, start: 0.000000, bitrate: 10086 kb/s
    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 81:256 DAR 9:16], 9970 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 180k tbc (default)
    Metadata:
      creation_time   : 2019-04-27T00:04:26.000000Z
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 162 kb/s (default)
    Metadata:
      creation_time   : 2019-04-27T00:04:26.000000Z
      handler_name    : SoundHandler
"""

In [10]:
ffmpeg_output = """
ffprobe version 4.1.3 Copyright (c) 2007-2019 the FFmpeg developers
  built with Apple LLVM version 10.0.1 (clang-1001.0.46.4)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1.3_1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/adoptopenjdk-11.0.2.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/adoptopenjdk-11.0.2.jdk/Contents/Home/include/darwin' --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-videotoolbox --disable-libjack --disable-indev=jack --enable-libaom --enable-libsoxr
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Tripptrappkuckuck.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 2019-04-27T00:12:09.000000Z
    title           : Tripptrappkuckuck
    date            : 2018-09-25T21:25:49+0200
    encoder         : HandBrake 1.2.1 2019021700
  Duration: 00:00:41.82, start: 0.000000, bitrate: 2030 kb/s
    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 1860 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 180k tbc (default)
    Metadata:
      creation_time   : 2019-04-27T00:12:09.000000Z
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 162 kb/s (default)
    Metadata:
      creation_time   : 2019-04-27T00:12:09.000000Z
      handler_name    : SoundHandler
"""

In [23]:
def get_video_dimensions(lines):
    def get_width_height(video_type, line):
        print(video_type, line)
        dim_col = line.split(", ")[3]
        if video_type != "h264":
            dim_col = dim_col.split(" ")[0]
        return map(int, dim_col.split("x"))

    width, height = None, None
    video_types = ("SAR", "hevc", "h264")
    for line in lines:
        for video_type in video_types:
            if video_type in line:
                width, height = get_width_height(video_type, line)
                break
        else:
            # necessary to break out of nested loop
            continue
        break
    portrait = False
    portrait_triggers = ["rotation of", "DAR 9:16"]
    for line in lines:
        for portrait_trigger in portrait_triggers:
            if portrait_trigger in line:
                print("heureka")
                portrait = True
    if portrait:
        width, height = height, width
    return width, height

In [24]:
get_video_dimensions(ffmpeg_output.split("\n"))


SAR     Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 81:256 DAR 9:16], 9970 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 180k tbc (default)
heureka
Out[24]:
(1080, 1920)