Générer un fichier .ts audio/vidéo à partir de listes .m3u

J’ai voulu récupérer une vidéo sur un site media mais impossible à télécharger avec youtube-dl. Examinons le format de ces listes et comment arriver à quand même télécharger le stream localement.

En examinant le player vidéo html5 (balise <video>) du site média, on remarque que 2 fichiers m3u sont téléchargés et lu par le navigateur en parallèle. Commençons déjà par les télécharger pour les analyser. Ces listes contiennent des liens vers des fichier .ts, c’est le principe du hls, découper en petits bouts d’trucs (les “segments”) le flux d’origine.

À noter que ces fichiers de liste de lecture sont généralement protégés d’un accès direct pour éviter le “hotlinking”, ils nécessitent d’envoyer les bons headers http, referer, cookie… Chose que fait votre navigateur “naturellement” lors d’une visite sur la page. Avec Firefox, on peut utiliser les devtools, et “copier l’url comme cURL” et enfin l’exécuter dans un terminal (commande que je vais suffixer avec -o playlistX.m3u pour enregistrer le fichier et non pas juste l’afficher sur la sortie standard).

Contenu de la 1ère liste playlist1.m3u :

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-TARGETDURATION:10
#EXTINF:9.920,
https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/ca7baf34-26be-439c-b50d-ac17a693b2e3/5x/segment0.ts
#EXTINF:9.920,
https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/ca7baf34-26be-439c-b50d-ac17a693b2e3/5x/segment1.ts
#EXTINF:9.920,
etc...

mediainfo indique qu’il n’y a qu’un flux audio dans chaque fichier :

$ mediainfo playlist1.m3u
General
ID                                       : 1 (0x1)
Complete name                            : https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/ca7baf34-26be-439c-b50d-ac17a693b2e3/5x/segment0.ts
Format                                   : MPEG-TS
File size                                : 303 KiB
Duration                                 : 9 s 899 ms
Overall bit rate mode                    : Variable
Overall bit rate                         : 250 kb/s

Audio
ID                                       : 257 (0x101)
Menu ID                                  : 1 (0x1)
Format                                   : AAC LC
Format/Info                              : Advanced Audio Codec Low Complexity
Format version                           : Version 4
Muxing mode                              : ADTS
Codec ID                                 : 15-2
Duration                                 : 9 s 898 ms
Bit rate mode                            : Variable
Channel(s)                               : 2 channels
Channel layout                           : L R
Sampling rate                            : 48.0 kHz
Frame rate                               : 46.875 FPS (1024 SPF)
Compression mode                         : Lossy

téléchargeons à la main les segments audio qui nous intéressent :

wget https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment0.ts
wget https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment1.ts
wget https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment2.ts

(il serait bon de scripter ceci pour télécharger tous les segments en une traite)

puis concaténons les :

cat segment0.ts segment1.ts segment2.ts > audio.ts

Contenu du 2ème m3u playlist2.m3u :

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-TARGETDURATION:10
#EXTINF:10.000,
https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment0.ts
#EXTINF:10.000,
https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment1.ts
etc...

mediainfo indique qu’il n’y a qu’un flux vidéo dans chaque fichier :

$ mediainfo playlist2.m3u
General
ID                                       : 1 (0x1)
Complete name                            : https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment0.ts
Format                                   : MPEG-TS
File size                                : 1.22 MiB
Duration                                 : 9 s 960 ms
Overall bit rate mode                    : Variable
Overall bit rate                         : 1 020 kb/s

Video
ID                                       : 258 (0x102)
Menu ID                                  : 1 (0x1)
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : Main@L3
Format settings                          : CABAC / 4 Ref Frames
Format settings, CABAC                   : Yes
Format settings, Reference frames        : 4 frames
Codec ID                                 : 27
Duration                                 : 10 s 0 ms
Bit rate                                 : 969 kb/s
Width                                    : 832 pixels
Height                                   : 468 pixels
Display aspect ratio                     : 16:9
Frame rate                               : 25.000 FPS
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Progressive
Bits/(Pixel*Frame)                       : 0.100
Stream size                              : 1.16 MiB (95%)

téléchargeons à la main les segments vidéo qui nous intéressent :

wget https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment0.ts
wget https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment1.ts
wget https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment2.ts

(il serait utile de scripter ceci pour télécharger tous les segments en une traite)

puis concaténons les :

cat segment0.ts segment1.ts segment2.ts > video.ts

Avec un peu de chance, on fusionne audio.ts et video.ts et on a enfin notre export !

ffmpeg -i audio.ts -i video.ts -c copy export.ts

Bon, ça marche presque mais on a une désynchro de plusieurs secondes entre le son et l’image … Si on regarde de plus près les infos données par mediainfo on remarque que le segment audio a une durée de 9 s 898 ms, et le segment vidéo une durée de 10 s 0 ms. Ça ne pouvait pas marcher.

Avec VLC, faisons le calcul manuel du décalage entre le son et l’image (touche G et F pour modifier l’offset). On arrive à la conclusion que le son doit être avancé de 2.750s (ou que la vidéo doit être reculée d’autant).

La commande magique de ffmpeg pour ce faire :

ffmpeg -i export-audio.ts -itsoffset 2.750 -i export-video.ts -c copy export-synchro.ts

En enfin un dernier traitement pour trimer le fichier plus finement (couper le début et la fin). Si je veux garder à partir de la 15ème seconde et jusqu’à 1min et 47sec :

ffmpeg -ss 00:00:15 -i export-synchro.ts -to 00:01:47 -c copy -avoid_negative_ts make_zero export-synchro-trim.ts

Et voilà !

comments powered by Disqus