
Recherche avancée
Médias (16)
-
#7 Ambience
16 octobre 2011, par
Mis à jour : Juin 2015
Langue : English
Type : Audio
-
#6 Teaser Music
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#5 End Title
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#3 The Safest Place
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#4 Emo Creates
15 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#2 Typewriter Dance
15 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
Autres articles (62)
-
MediaSPIP Core : La Configuration
9 novembre 2010, parMediaSPIP Core fournit par défaut trois pages différentes de configuration (ces pages utilisent le plugin de configuration CFG pour fonctionner) : une page spécifique à la configuration générale du squelettes ; une page spécifique à la configuration de la page d’accueil du site ; une page spécifique à la configuration des secteurs ;
Il fournit également une page supplémentaire qui n’apparait que lorsque certains plugins sont activés permettant de contrôler l’affichage et les fonctionnalités spécifiques (...) -
Des sites réalisés avec MediaSPIP
2 mai 2011, parCette page présente quelques-uns des sites fonctionnant sous MediaSPIP.
Vous pouvez bien entendu ajouter le votre grâce au formulaire en bas de page. -
Librairies et binaires spécifiques au traitement vidéo et sonore
31 janvier 2010, parLes logiciels et librairies suivantes sont utilisées par SPIPmotion d’une manière ou d’une autre.
Binaires obligatoires FFMpeg : encodeur principal, permet de transcoder presque tous les types de fichiers vidéo et sonores dans les formats lisibles sur Internet. CF ce tutoriel pour son installation ; Oggz-tools : outils d’inspection de fichiers ogg ; Mediainfo : récupération d’informations depuis la plupart des formats vidéos et sonores ;
Binaires complémentaires et facultatifs flvtool2 : (...)
Sur d’autres sites (8549)
-
AVPlayer currentTime not match with the displayed frame after many seeking. (HLS Stream)
26 août 2022, par D.BenceI have a m3u8 file which i want to use with HLS.
link to m3u8 file


My problem is that when i seek many times, the currentTime not match with the displayed frame. I experience that, the more seeking there is more difference. (it's like a constant +offset)


Our use case is very timing sensitive, we need to stop the videos at specific positions. For this we use the following code :


[_player addBoundaryTimeObserverForTimes:times
 queue:dispatch_get_main_queue()
 usingBlock:^{
 weakSelf.player.rate = 0.0;
 // The time is correct here, but the displayed frame is not sync with this time
 CMTimeShow(weakSelf.player.currentTime);
 }
] 



I read that AVURLAssetPreferPreciseDurationAndTimingKey can help, but the currentTime still wrong.


NSDictionary<nsstring> *options = @{AVURLAssetPreferPreciseDurationAndTimingKey:@YES};
AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:url options:options];
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:urlAsset];
</nsstring>


I also read that there is a problem with the m3u8 itself. (for example wrong GOP size.)


What is the reason for the incorrect currentTime, and how can i fix this ?


ffprobe m3u8 :


ffprobe https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized.m3u8
ffprobe version 5.1 Copyright (c) 2007-2022 the FFmpeg developers
 built with Apple clang version 13.1.6 (clang-1316.0.21.2.5)
 configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/5.1 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-neon
 libavutil 57. 28.100 / 57. 28.100
 libavcodec 59. 37.100 / 59. 37.100
 libavformat 59. 27.100 / 59. 27.100
 libavdevice 59. 7.100 / 59. 7.100
 libavfilter 8. 44.100 / 8. 44.100
 libswscale 6. 7.100 / 6. 7.100
 libswresample 4. 7.100 / 4. 7.100
 libpostproc 56. 6.100 / 56. 6.100
[hls @ 0x152f04280] Skip ('#EXT-X-VERSION:3')
[hls @ 0x152f04280] Skip ('#EXT-X-INDEPENDENT-SEGMENTS')
[hls @ 0x152f04280] Opening 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized1080p_6000000bitrate.m3u8' for reading
[hls @ 0x152f04280] Skip ('#EXT-X-VERSION:3')
[https @ 0x154045000] Opening 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized1080p_15000000bitrate.m3u8' for reading
[hls @ 0x152f04280] Skip ('#EXT-X-VERSION:3')
[https @ 0x154045000] Opening 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized1520p_33000000bitrate.m3u8' for reading
[hls @ 0x152f04280] Skip ('#EXT-X-VERSION:3')
[hls @ 0x152f04280] Opening 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized1080p_6000000bitrate_00001.ts' for reading
[hls @ 0x152f04280] Opening 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized1080p_6000000bitrate_00002.ts' for reading
[hls @ 0x152f04280] Opening 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized1080p_15000000bitrate_00001.ts' for reading
[hls @ 0x152f04280] Opening 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized1080p_15000000bitrate_00002.ts' for reading
[hls @ 0x152f04280] Opening 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized1520p_33000000bitrate_00001.ts' for reading
[hls @ 0x152f04280] Opening 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized1520p_33000000bitrate_00002.ts' for reading
Input #0, hls, from 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/released/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized.m3u8':
 Duration: 00:49:43.00, start: 2.033367, bitrate: 0 kb/s
 Program 0
 Metadata:
 variant_bitrate : 8133826
 Stream #0:0: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn
 Metadata:
 variant_bitrate : 8133826
 Program 1
 Metadata:
 variant_bitrate : 18870392
 Stream #0:1: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn
 Metadata:
 variant_bitrate : 18870392
 Program 2
 Metadata:
 variant_bitrate : 40776144
 Stream #0:2: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p, 2704x1520 [SAR 1:1 DAR 169:95], 29.97 fps, 29.97 tbr, 90k tbn
 Metadata:
 variant_bitrate : 40776144



ffprobe original mp4 :


ffprobe https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/finalized/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized.mp4
ffprobe version 5.1 Copyright (c) 2007-2022 the FFmpeg developers
 built with Apple clang version 13.1.6 (clang-1316.0.21.2.5)
 configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/5.1 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox --enable-neon
 libavutil 57. 28.100 / 57. 28.100
 libavcodec 59. 37.100 / 59. 37.100
 libavformat 59. 27.100 / 59. 27.100
 libavdevice 59. 7.100 / 59. 7.100
 libavfilter 8. 44.100 / 8. 44.100
 libswscale 6. 7.100 / 6. 7.100
 libswresample 4. 7.100 / 4. 7.100
 libpostproc 56. 6.100 / 56. 6.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'https://mrkresz-content-bucket.s3.eu-central-1.amazonaws.com/applicationData/extended-path-videos/4b0046fd-0be7-4a07-bc7c-c1a0069116b1/finalized/50816bc9-6118-4dd1-a90e-fb72652bb06f-final-from-anonymized.mp4':
 Metadata:
 major_brand : isom
 minor_version : 512
 compatible_brands: isomiso2avc1mp41
 encoder : Lavf58.76.100
 Duration: 00:49:42.81, start: 0.000000, bitrate: 36142 kb/s
 Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 2486x1398, 36138 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
 Metadata:
 handler_name : VideoHandler
 vendor_id : [0][0][0][0]



-
FFMPEG command runs in terminal but not by subprocess
1er septembre 2022, par BasiliqueI am trying to run a bash command using the
subprocess
module from withinpython 3.10
.

The bash command is :


ffmpeg -framerate 1 -pattern_type glob -i '*.png' -c:v libx264 -pix_fmt yuv420p -vf "crop=trunc(iw/2)*2:trunc(ih/2)*2" out.mp4



In terminal the command runs fine. Here is the output :


ffmpeg version 4.2.7-0ubuntu0.1 Copyright (c) 2000-2022 the FFmpeg developers
 built with gcc 9 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
 configuration: --prefix=/usr --extra-version=0ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
 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, image2, from '*.png':
 Duration: 00:16:39.00, start: 0.000000, bitrate: N/A
 Stream #0:0: Video: png, rgba(pc), 895x332 [SAR 3937:3937 DAR 895:332], 1 fps, 1 tbr, 1 tbn, 1 tbc
Stream mapping:
 Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x55726ab95d00] using SAR=1/1
[libx264 @ 0x55726ab95d00] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 AVX512
[libx264 @ 0x55726ab95d00] profile High, level 2.2
[libx264 @ 0x55726ab95d00] 264 - core 155 r2917 0a84d98 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=10 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=1 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'out.mp4':
 Metadata:
 encoder : Lavf58.29.100
 Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuv420p, 894x332 [SAR 1:1 DAR 447:166], q=-1--1, 1 fps, 16384 tbn, 1 tbc
 Metadata:
 encoder : Lavc58.54.100 libx264
 Side data:
 cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
frame= 173 fps=0.0 q=17.0 size= 512kB time=00:01:56.00 bitrate= 36.2kbits/frame= 351 fps=350 q=17.0 size= 1536kB time=00:04:54.00 bitrate= 42.8kbits/frame= 517 fps=343 q=17.0 size= 2560kB time=00:07:40.00 bitrate= 45.6kbits/frame= 725 fps=361 q=17.0 size= 3328kB time=00:11:08.00 bitrate= 40.8kbits/frame= 913 fps=364 q=17.0 size= 4352kB time=00:14:16.00 bitrate= 41.6kbits/frame= 999 fps=361 q=-1.0 Lsize= 4986kB time=00:16:36.00 bitrate= 41.0kbits/s speed= 360x 
video:4974kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.241361%
[libx264 @ 0x55726ab95d00] frame I:4 Avg QP: 6.12 size: 24072
[libx264 @ 0x55726ab95d00] frame P:346 Avg QP:12.94 size: 5708
[libx264 @ 0x55726ab95d00] frame B:649 Avg QP:18.19 size: 4655
[libx264 @ 0x55726ab95d00] consecutive B-frames: 5.8% 16.0% 20.1% 58.1%
[libx264 @ 0x55726ab95d00] mb I I16..4: 59.1% 10.6% 30.4%
[libx264 @ 0x55726ab95d00] mb P I16..4: 5.6% 0.6% 2.2% P16..4: 10.5% 4.3% 2.3% 0.0% 0.0% skip:74.5%
[libx264 @ 0x55726ab95d00] mb B I16..4: 2.2% 0.1% 1.7% B16..8: 16.9% 4.8% 1.6% direct: 1.1% skip:71.5% L0:50.9% L1:45.2% BI: 3.9%
[libx264 @ 0x55726ab95d00] 8x8 transform intra:5.9% inter:10.4%
[libx264 @ 0x55726ab95d00] coded y,uvDC,uvAC intra: 20.1% 18.3% 17.3% inter: 4.7% 4.7% 4.6%
[libx264 @ 0x55726ab95d00] i16 v,h,dc,p: 66% 33% 1% 0%
[libx264 @ 0x55726ab95d00] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 18% 8% 73% 0% 0% 0% 0% 0% 0%
[libx264 @ 0x55726ab95d00] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 23% 31% 31% 2% 3% 2% 4% 2% 3%
[libx264 @ 0x55726ab95d00] i8c dc,h,v,p: 73% 23% 3% 0%
[libx264 @ 0x55726ab95d00] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x55726ab95d00] ref P L0: 57.2% 1.5% 24.3% 17.0%
[libx264 @ 0x55726ab95d00] ref B L0: 69.6% 24.8% 5.6%
[libx264 @ 0x55726ab95d00] ref B L1: 92.4% 7.6%
[libx264 @ 0x55726ab95d00] kb/s:40.78



In my python script I tried the following solutions :


video_cmd = """ffmpeg -framerate 1 -pattern_type glob -i '*.png' -c:v libx264 -pix_fmt yuv420p -vf "crop=trunc(iw/2)*2:trunc(ih/2)*2" out.mp4"""

subprocess.run(shlex.split(video_cmd), shell=False, cwd=path_viz, stderr=subprocess.STDOUT, check=True, text=False)

subprocess.run(video_cmd, shell=True, cwd=path_viz, stderr=subprocess.STDOUT, check=True, text=False)



as well as the solution proposed for this similar question


subprocess.Popen(video_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)



None of them worked. Apparently, the right command is run (output of the
check_out
function) :

Command 'ffmpeg -y -framerate 1 -pattern_type glob -i '*.png' -c:v libx264 -pix_fmt yuv420p -vf "crop=trunc(iw/2)*2:trunc(ih/2)*2" out.mp4' returned non-zero exit status 1.



the first part of the job (up to
Stream mapping:
) is done also correctly :

fmpeg version 4.3 Copyright (c) 2000-2020 the FFmpeg developers
 built with gcc 7.3.0 (crosstool-NG 1.23.0.449-a04d0)
 configuration: --prefix=/home/rsghazanfari/anaconda3/envs/_cuda --cc=/opt/conda/conda-bld/ffmpeg_1597178665428/_build_env/bin/x86_64-conda_cos6-linux-gnu-cc --disable-doc --disable-openssl --enable-avresample --enable-gnutls --enable-hardcoded-tables --enable-libfreetype --enable-libopenh264 --enable-pic --enable-pthreads --enable-shared --disable-static --enable-version3 --enable-zlib --enable-libmp3lame
 libavutil 56. 51.100 / 56. 51.100
 libavcodec 58. 91.100 / 58. 91.100
 libavformat 58. 45.100 / 58. 45.100
 libavdevice 58. 10.100 / 58. 10.100
 libavfilter 7. 85.100 / 7. 85.100
 libavresample 4. 0. 0 / 4. 0. 0
 libswscale 5. 7.100 / 5. 7.100
 libswresample 3. 7.100 / 3. 7.100
Input #0, image2, from '*.png':
 Duration: 00:16:39.00, start: 0.000000, bitrate: N/A
 Stream #0:0: Video: png, rgba(pc), 895x332 [SAR 3937:3937 DAR 895:332], 1 fps, 1 tbr, 1 tbn, 1 tbc



but it then pops up the following error :


Unknown encoder 'libx264'
Traceback (most recent call last):
 File "/home/rsgh/anaconda3/envs/_cuda/lib/python3.10/code.py", line 90, in runcode
 exec(code, self.locals)
 File "<input />", line 1, in <module>
 File "/home/rsgh/anaconda3/envs/_cuda/lib/python3.10/subprocess.py", line 524, in run
 raise CalledProcessError(retcode, process.args,

subprocess.CalledProcessError: Command 'ffmpeg -y -framerate 1 -pattern_type glob -i '*.png' -c:v libx264 -pix_fmt yuv420p -vf "crop=trunc(iw/2)*2:trunc(ih/2)*2" out.mp4' returned non-zero exit status 1.
</module>


Any ideas of why this error is produced in python while in terminal it runs fine ? Thank you in advance.


PS :
ffmpeg -version
outputs :

ffmpeg version 4.2.7-0ubuntu0.1 Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 9 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
configuration: --prefix=/usr --extra-version=0ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
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



ubuntu version :


Distributor ID: Ubuntu
Description: Ubuntu 20.04.4 LTS
Release: 20.04
Codename: focal



-
Getting shifted timestamps when encoding a fragmented h264 mp4 with ffmpeg
14 septembre 2022, par Martin CastinI am trying to encode a fragmented h264 mp4 with ffmpeg. I tried the following command :


ffmpeg -i input.mp4 -movflags +frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov output.mp4



It does give me a fragmented mp4 but the timestamps of the frames seem to be shifted by 0.04s when I read the video with mpv. The first frame has a timestamp of 0.04s instead of 0s, as in the input video (1920x1080, 50 fps). I encountered the problem both with ffmpeg 5.1 and ffmpeg 3.4.11.


I tried to add several flags, as
-avoid_negative_ts make_zero
or-copyts -output_ts_offset -0.04
, but it did not help.

I am also trying to achieve this using the ffmpeg libav libraries in C++ but did not get to better result. Here are the code fragments I used.


avformat_alloc_output_context2(&oc, NULL, NULL, filename);

 if (oc_->oformat->flags & AVFMT_GLOBALHEADER) {
 codecCtx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
 }
...
 AVDictionary* opts = NULL;

 av_dict_set(&opts, "movflags", "frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov", 0);

 ret = avformat_write_header(oc_, &opts);



Do you know how to avoid this behaviour of shifted timestamps for fragmented mp4, either with ffmpeg or libav ?


Edit : example videos and complete code example


I also tried with the following ffmpeg build


ffmpeg version 5.0.1-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 8 (Debian 8.3.0-6)
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
libavutil 57. 17.100 / 57. 17.100
libavcodec 59. 18.100 / 59. 18.100
libavformat 59. 16.100 / 59. 16.100
libavdevice 59. 4.100 / 59. 4.100
libavfilter 8. 24.100 / 8. 24.100
libswscale 6. 4.100 / 6. 4.100
libswresample 4. 3.100 / 4. 3.100
libpostproc 56. 3.100 / 56. 3.100



and with the sintel trailer as input video, which is 24fps, and I thus get a timeshift of 83ms. Here is the output I get.


Here is a complete code example, slightly adapted from the
muxing.c
ffmpeg example (audio removed and adapted for c++). This code shows exactly the same problem.

You can just comment the line 383 (that is calling
av_dict_set
) to switch back to a not fragmented mp4 that will not have the timestamp shift.

/*
 * Copyright (c) 2003 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * @file
 * libavformat API example.
 *
 * Output a media file in any supported libavformat format. The default
 * codecs are used.
 * @example muxing.c
 */

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>

extern "C"
{
#define __STDC_CONSTANT_MACROS
#include <libavutil></libavutil>avassert.h>
#include <libavutil></libavutil>channel_layout.h>
#include <libavutil></libavutil>opt.h>
#include <libavutil></libavutil>mathematics.h>
#include <libavutil></libavutil>timestamp.h>
#include <libavcodec></libavcodec>avcodec.h>
#include <libavformat></libavformat>avformat.h>
#include <libswscale></libswscale>swscale.h>
#include <libswresample></libswresample>swresample.h>
}

#define STREAM_DURATION 10.0
#define STREAM_FRAME_RATE 25 /* 25 images/s */
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */

#define SCALE_FLAGS SWS_BICUBIC

// a wrapper around a single output AVStream
typedef struct OutputStream {
 AVStream *st;
 AVCodecContext *enc;

 /* pts of the next frame that will be generated */
 int64_t next_pts;
 int samples_count;

 AVFrame *frame;
 AVFrame *tmp_frame;

 AVPacket *tmp_pkt;

 float t, tincr, tincr2;

 struct SwsContext *sws_ctx;
 struct SwrContext *swr_ctx;
} OutputStream;

static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
{
 AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;

// printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
// av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
// av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
// av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
// pkt->stream_index);
}

static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,
 AVStream *st, AVFrame *frame, AVPacket *pkt)
{
 int ret;

 // send the frame to the encoder
 ret = avcodec_send_frame(c, frame);
 if (ret < 0) {
 fprintf(stderr, "Error sending a frame to the encoder");
 exit(1);
 }

 while (ret >= 0) {
 ret = avcodec_receive_packet(c, pkt);
 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
 break;
 else if (ret < 0) {
 fprintf(stderr, "Error encoding a frame\n");
 exit(1);
 }

 /* rescale output packet timestamp values from codec to stream timebase */
 av_packet_rescale_ts(pkt, c->time_base, st->time_base);
 pkt->stream_index = st->index;

 /* Write the compressed frame to the media file. */
 log_packet(fmt_ctx, pkt);
 ret = av_interleaved_write_frame(fmt_ctx, pkt);
 /* pkt is now blank (av_interleaved_write_frame() takes ownership of
 * its contents and resets pkt), so that no unreferencing is necessary.
 * This would be different if one used av_write_frame(). */
 if (ret < 0) {
 fprintf(stderr, "Error while writing output packet\n");
 exit(1);
 }
 }

 return ret == AVERROR_EOF ? 1 : 0;
}

/* Add an output stream. */
static void add_stream(OutputStream *ost, AVFormatContext *oc,
 const AVCodec **codec,
 enum AVCodecID codec_id)
{
 AVCodecContext *c;
 int i;

 /* find the encoder */
 *codec = avcodec_find_encoder(codec_id);
 if (!(*codec)) {
 fprintf(stderr, "Could not find encoder for '%s'\n",
 avcodec_get_name(codec_id));
 exit(1);
 }

 ost->tmp_pkt = av_packet_alloc();
 if (!ost->tmp_pkt) {
 fprintf(stderr, "Could not allocate AVPacket\n");
 exit(1);
 }

 ost->st = avformat_new_stream(oc, NULL);
 if (!ost->st) {
 fprintf(stderr, "Could not allocate stream\n");
 exit(1);
 }
 ost->st->id = oc->nb_streams-1;
 c = avcodec_alloc_context3(*codec);
 if (!c) {
 fprintf(stderr, "Could not alloc an encoding context\n");
 exit(1);
 }
 ost->enc = c;

 switch ((*codec)->type) {
 case AVMEDIA_TYPE_VIDEO:
 c->codec_id = codec_id;

 c->bit_rate = 400000;
 /* Resolution must be a multiple of two. */
 c->width = 352;
 c->height = 288;
 /* timebase: This is the fundamental unit of time (in seconds) in terms
 * of which frame timestamps are represented. For fixed-fps content,
 * timebase should be 1/framerate and timestamp increments should be
 * identical to 1. */
 ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE };
 c->time_base = ost->st->time_base;

 c->gop_size = 12; /* emit one intra frame every twelve frames at most */
 c->pix_fmt = STREAM_PIX_FMT;
 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
 /* just for testing, we also add B-frames */
 c->max_b_frames = 2;
 }
 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
 /* Needed to avoid using macroblocks in which some coeffs overflow.
 * This does not happen with normal video, it just happens here as
 * the motion of the chroma plane does not match the luma plane. */
 c->mb_decision = 2;
 }
 break;

 default:
 break;
 }

 /* Some formats want stream headers to be separate. */
 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}

/**************************************************************/
/* video output */

static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
{
 AVFrame *picture;
 int ret;

 picture = av_frame_alloc();
 if (!picture)
 return NULL;

 picture->format = pix_fmt;
 picture->width = width;
 picture->height = height;

 /* allocate the buffers for the frame data */
 ret = av_frame_get_buffer(picture, 0);
 if (ret < 0) {
 fprintf(stderr, "Could not allocate frame data.\n");
 exit(1);
 }

 return picture;
}

static void open_video(AVFormatContext *oc, const AVCodec *codec,
 OutputStream *ost, AVDictionary *opt_arg)
{
 int ret;
 AVCodecContext *c = ost->enc;
 AVDictionary *opt = NULL;

 av_dict_copy(&opt, opt_arg, 0);

 /* open the codec */
 ret = avcodec_open2(c, codec, &opt);
 av_dict_free(&opt);
 if (ret < 0) {
 fprintf(stderr, "Could not open video codec\n");
 exit(1);
 }

 /* allocate and init a re-usable frame */
 ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
 if (!ost->frame) {
 fprintf(stderr, "Could not allocate video frame\n");
 exit(1);
 }

 /* If the output format is not YUV420P, then a temporary YUV420P
 * picture is needed too. It is then converted to the required
 * output format. */
 ost->tmp_frame = NULL;
 if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
 ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
 if (!ost->tmp_frame) {
 fprintf(stderr, "Could not allocate temporary picture\n");
 exit(1);
 }
 }

 /* copy the stream parameters to the muxer */
 ret = avcodec_parameters_from_context(ost->st->codecpar, c);
 if (ret < 0) {
 fprintf(stderr, "Could not copy the stream parameters\n");
 exit(1);
 }
}

/* Prepare a dummy image. */
static void fill_yuv_image(AVFrame *pict, int frame_index,
 int width, int height)
{
 int x, y, i;

 i = frame_index;

 /* Y */
 for (y = 0; y < height; y++)
 for (x = 0; x < width; x++)
 pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;

 /* Cb and Cr */
 for (y = 0; y < height / 2; y++) {
 for (x = 0; x < width / 2; x++) {
 pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
 pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
 }
 }
}

static AVFrame *get_video_frame(OutputStream *ost)
{
 AVCodecContext *c = ost->enc;

 /* check if we want to generate more frames */
 if (av_compare_ts(ost->next_pts, c->time_base,
 STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
 return NULL;

 /* when we pass a frame to the encoder, it may keep a reference to it
 * internally; make sure we do not overwrite it here */
 if (av_frame_make_writable(ost->frame) < 0)
 exit(1);

 if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
 /* as we only generate a YUV420P picture, we must convert it
 * to the codec pixel format if needed */
 if (!ost->sws_ctx) {
 ost->sws_ctx = sws_getContext(c->width, c->height,
 AV_PIX_FMT_YUV420P,
 c->width, c->height,
 c->pix_fmt,
 SCALE_FLAGS, NULL, NULL, NULL);
 if (!ost->sws_ctx) {
 fprintf(stderr,
 "Could not initialize the conversion context\n");
 exit(1);
 }
 }
 fill_yuv_image(ost->tmp_frame, ost->next_pts, c->width, c->height);
 sws_scale(ost->sws_ctx, (const uint8_t * const *) ost->tmp_frame->data,
 ost->tmp_frame->linesize, 0, c->height, ost->frame->data,
 ost->frame->linesize);
 } else {
 fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);
 }

 ost->frame->pts = ost->next_pts++;

 return ost->frame;
}

/*
 * encode one video frame and send it to the muxer
 * return 1 when encoding is finished, 0 otherwise
 */
static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
{
 return write_frame(oc, ost->enc, ost->st, get_video_frame(ost), ost->tmp_pkt);
}

static void close_stream(AVFormatContext *oc, OutputStream *ost)
{
 avcodec_free_context(&ost->enc);
 av_frame_free(&ost->frame);
 av_frame_free(&ost->tmp_frame);
 av_packet_free(&ost->tmp_pkt);
 sws_freeContext(ost->sws_ctx);
 swr_free(&ost->swr_ctx);
}

/**************************************************************/
/* media file output */

int main(int argc, char **argv)
{
 OutputStream video_st = { 0 }, audio_st = { 0 };
 const AVOutputFormat *fmt;
 const char *filename;
 AVFormatContext *oc;
 const AVCodec *audio_codec, *video_codec;
 int ret;
 int have_video = 0, have_audio = 0;
 int encode_video = 0, encode_audio = 0;
 AVDictionary *opt = NULL;
 int i;

 if (argc < 2) {
 printf("usage: %s output_file\n"
 "API example program to output a media file with libavformat.\n"
 "This program generates a synthetic audio and video stream, encodes and\n"
 "muxes them into a file named output_file.\n"
 "The output format is automatically guessed according to the file extension.\n"
 "Raw images can also be output by using '%%d' in the filename.\n"
 "\n", argv[0]);
 return 1;
 }

 filename = argv[1];

 av_dict_set(&opt, "movflags", "frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov", 0);

 /* allocate the output media context */
 avformat_alloc_output_context2(&oc, NULL, NULL, filename);
 if (!oc) {
 printf("Could not deduce output format from file extension: using MPEG.\n");
 avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
 }
 if (!oc)
 return 1;

 fmt = oc->oformat;

 /* Add the audio and video streams using the default format codecs
 * and initialize the codecs. */
 if (fmt->video_codec != AV_CODEC_ID_NONE) {
 add_stream(&video_st, oc, &video_codec, fmt->video_codec);
 have_video = 1;
 encode_video = 1;
 }

 /* Now that all the parameters are set, we can open the audio and
 * video codecs and allocate the necessary encode buffers. */
 if (have_video)
 open_video(oc, video_codec, &video_st, opt);


 av_dump_format(oc, 0, filename, 1);

 /* open the output file, if needed */
 if (!(fmt->flags & AVFMT_NOFILE)) {
 ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
 if (ret < 0) {
 fprintf(stderr, "Could not open '%s'\n", filename);
 return 1;
 }
 }

 /* Write the stream header, if any. */
 ret = avformat_write_header(oc, &opt);
 if (ret < 0) {
 fprintf(stderr, "Error occurred when opening output file\n");
 return 1;
 }

 while (encode_video || encode_audio) {
 /* select the stream to encode */
 if (encode_video &&
 (!encode_audio || av_compare_ts(video_st.next_pts, video_st.enc->time_base,
 audio_st.next_pts, audio_st.enc->time_base) <= 0)) {
 encode_video = !write_video_frame(oc, &video_st);
 }
 }

 av_write_trailer(oc);

 /* Close each codec. */
 if (have_video)
 close_stream(oc, &video_st);
 if (have_audio)
 close_stream(oc, &audio_st);

 if (!(fmt->flags & AVFMT_NOFILE))
 /* Close the output file. */
 avio_closep(&oc->pb);

 /* free the stream */
 avformat_free_context(oc);

 return 0;
}
</cmath></cstring></cstdio></cstdlib>