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 :

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

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

 1$ mediainfo playlist1.m3u
 2General
 3ID                                       : 1 (0x1)
 4Complete 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
 5Format                                   : MPEG-TS
 6File size                                : 303 KiB
 7Duration                                 : 9 s 899 ms
 8Overall bit rate mode                    : Variable
 9Overall bit rate                         : 250 kb/s
10
11Audio
12ID                                       : 257 (0x101)
13Menu ID                                  : 1 (0x1)
14Format                                   : AAC LC
15Format/Info                              : Advanced Audio Codec Low Complexity
16Format version                           : Version 4
17Muxing mode                              : ADTS
18Codec ID                                 : 15-2
19Duration                                 : 9 s 898 ms
20Bit rate mode                            : Variable
21Channel(s)                               : 2 channels
22Channel layout                           : L R
23Sampling rate                            : 48.0 kHz
24Frame rate                               : 46.875 FPS (1024 SPF)
25Compression mode                         : Lossy

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

1wget https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment0.ts
2wget https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment1.ts
3wget 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 :

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

Contenu du 2ème m3u playlist2.m3u :

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

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

 1$ mediainfo playlist2.m3u
 2General
 3ID                                       : 1 (0x1)
 4Complete 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
 5Format                                   : MPEG-TS
 6File size                                : 1.22 MiB
 7Duration                                 : 9 s 960 ms
 8Overall bit rate mode                    : Variable
 9Overall bit rate                         : 1 020 kb/s
10
11Video
12ID                                       : 258 (0x102)
13Menu ID                                  : 1 (0x1)
14Format                                   : AVC
15Format/Info                              : Advanced Video Codec
16Format profile                           : Main@L3
17Format settings                          : CABAC / 4 Ref Frames
18Format settings, CABAC                   : Yes
19Format settings, Reference frames        : 4 frames
20Codec ID                                 : 27
21Duration                                 : 10 s 0 ms
22Bit rate                                 : 969 kb/s
23Width                                    : 832 pixels
24Height                                   : 468 pixels
25Display aspect ratio                     : 16:9
26Frame rate                               : 25.000 FPS
27Color space                              : YUV
28Chroma subsampling                       : 4:2:0
29Bit depth                                : 8 bits
30Scan type                                : Progressive
31Bits/(Pixel*Frame)                       : 0.100
32Stream size                              : 1.16 MiB (95%)

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

1wget https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment0.ts
2wget https://bcboltnexti1-a.akamaihd.net/media/v1/hls/v4/clear/5132998232001/1bc7de60-1e1d-48cb-a747-60e599c7fc18/70d863bc-68c2-42e4-a020-0542af0ef2e0/5x/segment1.ts
3wget 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 :

1cat 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 !

1ffmpeg -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 :

1ffmpeg -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 :

1ffmpeg -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