russellaugust
russellaugust

Reputation: 358

Get Timecode from MP4 generated in Adobe Premiere / Encoder in Python and FFMPEG

I'm writing a script that needs to either convert or re-container an MP4 as an MOV with timecode.

I have an MP4 generated from Adobe Premiere. If I bring that file back into Premiere, I have timecode. I can see it so I know it is there.

I can't seem to extract the timecode track from the MP4. I've looked everywhere online and found some discussions around it, but no actual success in extracting the timecode.

I've been using ffprobe to see if there's any mention of the timecode in the MP4, but having no luck. I've tried PyMediaInfo with no success.

Here's what ffprobe shows:


ffprobe version 4.2.1 Copyright (c) 2007-2019 the FFmpeg developers
  built with Apple clang version 11.0.0 (clang-1100.0.33.8)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.2.1_1 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home/include/darwin -fno-stack-check' --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-libvidstab --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-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'demo_SequenceV3.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42mp41
    creation_time   : 2019-11-01T23:34:45.000000Z
  Duration: 00:00:27.69, start: 0.000000, bitrate: 10463 kb/s
    Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 2304x1152 [SAR 1:1 DAR 2:1], 10142 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 48k tbc (default)
    Metadata:
      creation_time   : 2019-11-01T23:34:45.000000Z
      handler_name    : ?Mainconcept Video Media Handler
      encoder         : AVC Coding
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 317 kb/s (default)
    Metadata:
      creation_time   : 2019-11-01T23:34:46.000000Z
      handler_name    : #Mainconcept MP4 Sound Media Handler
[STREAM]
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
profile=Main
codec_type=video
codec_time_base=1001/48000
codec_tag_string=avc1
codec_tag=0x31637661
width=2304
height=1152
coded_width=2304
coded_height=1152
has_b_frames=0
sample_aspect_ratio=1:1
display_aspect_ratio=2:1
pix_fmt=yuv420p
level=50
color_range=tv
color_space=bt709
color_transfer=bt709
color_primaries=bt709
chroma_location=left
field_order=unknown
timecode=N/A
refs=1
is_avc=true
nal_length_size=4
id=N/A
r_frame_rate=24000/1001
avg_frame_rate=24000/1001
time_base=1/24000
start_pts=0
start_time=0.000000
duration_ts=663663
duration=27.652625
bit_rate=10142082
max_bit_rate=N/A
bits_per_raw_sample=8
nb_frames=663
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:creation_time=2019-11-01T23:34:45.000000Z
TAG:language=eng
TAG:handler_name=Mainconcept Video Media Handler
TAG:encoder=AVC Coding
[/STREAM]
[STREAM]
index=1
codec_name=aac
codec_long_name=AAC (Advanced Audio Coding)
profile=LC
codec_type=audio
codec_time_base=1/48000
codec_tag_string=mp4a
codec_tag=0x6134706d
sample_fmt=fltp
sample_rate=48000
channels=2
channel_layout=stereo
bits_per_sample=0
id=N/A
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/48000
start_pts=0
start_time=0.000000
duration_ts=1327326
duration=27.652625
bit_rate=317375
max_bit_rate=335623
bits_per_raw_sample=N/A
nb_frames=1298
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:creation_time=2019-11-01T23:34:46.000000Z
TAG:language=eng
TAG:handler_name=#Mainconcept MP4 Sound Media Handler
[/STREAM]
[FORMAT]
filename=demo_SequenceV3.mp4
nb_streams=2
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=27.690667
size=36216937
bit_rate=10463290
probe_score=100
TAG:major_brand=mp42
TAG:minor_version=0
TAG:compatible_brands=mp42mp41
TAG:creation_time=2019-11-01T23:34:45.000000Z
[/FORMAT]

And here was what I started experimenting with in Python.

from pymediainfo import MediaInfo

media_info = MediaInfo.parse('demo_SequenceV3.mp4')
for track in media_info.tracks:
    if track.bit_rate is not None:
        print ("%s: %s" % (track.track_type, track.bit_rate))
    else:
        print ("""%s tracks do not have bit rate associated with them.""" % track.track_type)

I know I'm not using MediaInfo correctly, but I couldn't find any documentation on timecode, and to be honest I'm pretty confident it'll just use FFMPEG's system of searching for a data track that doesn't appear to exist.

Anyone here know enough about this to either get it working or to point me in the right direction?

The goal is to re-wrap an MP4 as an MOV and translate the timecode so it is back where it normally is on the MOV.

EDIT: here is an example MP4 that I need to extract the timecode from:

https://www.dropbox.com/s/a1euiumiapkpzhn/timecode_demo.mp4?dl=0

And as you can see in this image, the MP4 does have timecode that is being read by Premiere on the bottom left of frame. TC starts at 10:11:12:13.

https://www.dropbox.com/s/pafqicnnsqu93rl/timecode_window_in_premiere.png

Upvotes: 0

Views: 2011

Answers (1)

Gyan
Gyan

Reputation: 93241

The timecode is stored in an Adobe specific format (XMP) which ffmpeg does not normally parse and even when it does, it just treats it as a raw blob.

You can use a similar command to the one below to extract the TC and then remux the file using ffmpeg by passing -timecode EXTRACTED_VALUE

ffmpeg -export_xmp true -i timecode_demo.mp4 2>&1 | grep -A 5 -i starttimecode | grep -ioP "(?<=timevalue=\")[0-9:]+" | head -1

The above extracts

10:11:12:13

If you're using Mediainfo API, look for the TIM metadata key, but I can't verify this will work.

Upvotes: 1

Related Questions