ffmpegwasm/ffmpeg.wasm

FFmpeg M3U8 to MP4 Conversion Only Includes Initial Segment

Jason-liu-0219 opened this issue · 1 comments

Describe the bug
I am trying to convert an M3U8 playlist containing .m4s segments into an MP4 file. However, after conversion, I can only retrieve the duration of the media0.m4s file, and the full video is incomplete. I am unsure whether there is an issue with my implementation or if something else is causing the problem. Could you please help me identify the issue?

To Reproduce

// m3u8 list content
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-DISCONTINUITY
#EXT-X-MAP:URI="media0.m4s",BYTERANGE="880@0"
#EXTINF:4.870000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:00.000Z
#EXT-X-BYTERANGE:129598@880
media0.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:04.870Z
#EXT-X-BYTERANGE:158810@130478
media0.m4s
#EXTINF:9.870000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:08.966Z
#EXT-X-BYTERANGE:126427@289288
media0.m4s
#EXTINF:5.040000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:18.836Z
#EXT-X-BYTERANGE:130566@415715
media0.m4s
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:23.876Z
#EXT-X-BYTERANGE:101729@546281
media0.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:28.022Z
#EXT-X-BYTERANGE:232388@648010
media0.m4s
#EXTINF:9.746667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:32.118Z
#EXT-X-BYTERANGE:165126@880398
media0.m4s
#EXTINF:4.986667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:41.864Z
#EXT-X-BYTERANGE:101530@1045524
media0.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:46.850Z
#EXT-X-BYTERANGE:117064@1147054
media0.m4s
#EXTINF:6.200000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:50.950Z
#EXT-X-BYTERANGE:90950@1264118
media0.m4s
#EXTINF:6.196667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:00:57.150Z
#EXT-X-BYTERANGE:86655@1355068
media0.m4s
#EXTINF:4.193333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:03.346Z
#EXT-X-BYTERANGE:119887@1441723
media0.m4s
#EXTINF:6.180000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:07.539Z
#EXT-X-BYTERANGE:131583@1561610
media0.m4s
#EXTINF:4.153333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:13.719Z
#EXT-X-BYTERANGE:161352@1693193
media0.m4s
#EXTINF:4.103333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:17.872Z
#EXT-X-BYTERANGE:221917@1854545
media0.m4s
#EXTINF:4.866667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:21.975Z
#EXT-X-BYTERANGE:127826@2076462
media0.m4s
#EXTINF:5.020000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:26.841Z
#EXT-X-BYTERANGE:121535@2204288
media0.m4s
#EXTINF:6.200000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:31.861Z
#EXT-X-BYTERANGE:135361@2325823
media0.m4s
#EXTINF:6.190000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:38.061Z
#EXT-X-BYTERANGE:119239@2461184
media0.m4s
#EXTINF:4.106667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:44.251Z
#EXT-X-BYTERANGE:141680@2580423
media0.m4s
#EXTINF:4.196667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:48.357Z
#EXT-X-BYTERANGE:153679@2722103
media0.m4s
#EXTINF:4.140000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:52.553Z
#EXT-X-BYTERANGE:136059@2875782
media0.m4s
#EXTINF:9.990000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:01:56.693Z
#EXT-X-BYTERANGE:107205@3011841
media0.m4s
#EXTINF:8.140000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:06.683Z
#EXT-X-BYTERANGE:102982@3119046
media0.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:14.823Z
#EXT-X-BYTERANGE:114009@3222028
media0.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:18.973Z
#EXT-X-BYTERANGE:164494@3336037
media0.m4s
#EXTINF:4.770000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:23.069Z
#EXT-X-BYTERANGE:113445@3500531
media0.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:27.839Z
#EXT-X-BYTERANGE:160793@3613976
media0.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:31.939Z
#EXT-X-BYTERANGE:165761@3774769
media0.m4s
#EXTINF:4.143333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:36.089Z
#EXT-X-BYTERANGE:157323@3940530
media0.m4s
#EXTINF:3.563333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:40.232Z
#EXT-X-BYTERANGE:197571@4097853
media0.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:43.795Z
#EXT-X-BYTERANGE:221690@4295424
media0.m4s
#EXTINF:4.880000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:47.945Z
#EXT-X-BYTERANGE:112936@4517114
media0.m4s
#EXTINF:4.103333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:52.825Z
#EXT-X-BYTERANGE:109277@4630050
media0.m4s
#EXTINF:6.193333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:02:56.928Z
#EXT-X-BYTERANGE:131492@4739327
media0.m4s
#EXTINF:8.723333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:03.121Z
#EXT-X-BYTERANGE:81894@4870819
media0.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:11.844Z
#EXT-X-BYTERANGE:127691@4952713
media0.m4s
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:15.944Z
#EXT-X-BYTERANGE:173093@5080404
media0.m4s
#EXT-X-DISCONTINUITY
#EXT-X-MAP:URI="media1.m4s",BYTERANGE="880@0"
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:20.090Z
#EXT-X-BYTERANGE:176896@880
media1.m4s
#EXTINF:4.576667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:24.236Z
#EXT-X-BYTERANGE:119074@177776
media1.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:28.812Z
#EXT-X-BYTERANGE:180189@296850
media1.m4s
#EXTINF:10.006667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:32.962Z
#EXT-X-BYTERANGE:112231@477039
media1.m4s
#EXTINF:4.863333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:42.968Z
#EXT-X-BYTERANGE:83603@589270
media1.m4s
#EXTINF:4.140000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:47.831Z
#EXT-X-BYTERANGE:186326@672873
media1.m4s
#EXTINF:6.193333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:51.971Z
#EXT-X-BYTERANGE:129747@859199
media1.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:03:58.164Z
#EXT-X-BYTERANGE:125875@988946
media1.m4s
#EXTINF:6.573333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:04:02.264Z
#EXT-X-BYTERANGE:75883@1114821
media1.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:04:08.837Z
#EXT-X-BYTERANGE:118823@1190704
media1.m4s
#EXTINF:5.893333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:04:12.933Z
#EXT-X-BYTERANGE:119777@1309527
media1.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:04:18.826Z
#EXT-X-BYTERANGE:92153@1429304
media1.m4s
#EXTINF:6.253333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:04:22.922Z
#EXT-X-BYTERANGE:114673@1521457
media1.m4s
#EXTINF:4.650000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:04:29.175Z
#EXT-X-BYTERANGE:97537@1636130
media1.m4s
#EXTINF:3.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:04:33.825Z
#EXT-X-BYTERANGE:195165@1733667
media1.m4s
#EXTINF:6.193333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:04:36.921Z
#EXT-X-BYTERANGE:211351@1928832
media1.m4s
#EXTINF:10.016667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:04:43.114Z
#EXT-X-BYTERANGE:88978@2140183
media1.m4s
#EXTINF:9.996667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:04:53.130Z
#EXT-X-BYTERANGE:51891@2229161
media1.m4s
#EXTINF:4.720000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:03.126Z
#EXT-X-BYTERANGE:69656@2281052
media1.m4s
#EXTINF:4.143333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:07.846Z
#EXT-X-BYTERANGE:134622@2350708
media1.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:11.989Z
#EXT-X-BYTERANGE:190952@2485330
media1.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:16.089Z
#EXT-X-BYTERANGE:125461@2676282
media1.m4s
#EXTINF:4.143333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:20.239Z
#EXT-X-BYTERANGE:185594@2801743
media1.m4s
#EXTINF:4.140000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:24.382Z
#EXT-X-BYTERANGE:219074@2987337
media1.m4s
#EXTINF:4.360000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:28.522Z
#EXT-X-BYTERANGE:147866@3206411
media1.m4s
#EXTINF:4.093333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:32.882Z
#EXT-X-BYTERANGE:187350@3354277
media1.m4s
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:36.975Z
#EXT-X-BYTERANGE:126158@3541627
media1.m4s
#EXTINF:6.236667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:41.121Z
#EXT-X-BYTERANGE:80611@3667785
media1.m4s
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:47.357Z
#EXT-X-BYTERANGE:102564@3748396
media1.m4s
#EXTINF:4.136667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:51.503Z
#EXT-X-BYTERANGE:126453@3850960
media1.m4s
#EXTINF:9.996667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:05:55.639Z
#EXT-X-BYTERANGE:124795@3977413
media1.m4s
#EXTINF:5.196667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:05.635Z
#EXT-X-BYTERANGE:95821@4102208
media1.m4s
#EXTINF:3.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:10.831Z
#EXT-X-BYTERANGE:187703@4198029
media1.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:13.931Z
#EXT-X-BYTERANGE:157642@4385732
media1.m4s
#EXTINF:4.140000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:18.027Z
#EXT-X-BYTERANGE:197888@4543374
media1.m4s
#EXTINF:4.190000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:22.167Z
#EXT-X-BYTERANGE:171008@4741262
media1.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:26.357Z
#EXT-X-BYTERANGE:129441@4912270
media1.m4s
#EXTINF:4.143333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:30.453Z
#EXT-X-BYTERANGE:182096@5041711
media1.m4s
#EXTINF:4.153333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:34.596Z
#EXT-X-BYTERANGE:100740@5223807
media1.m4s
#EXT-X-DISCONTINUITY
#EXT-X-MAP:URI="media2.m4s",BYTERANGE="880@0"
#EXTINF:6.200000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:38.749Z
#EXT-X-BYTERANGE:91471@880
media2.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:44.949Z
#EXT-X-BYTERANGE:157522@92351
media2.m4s
#EXTINF:6.233333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:49.045Z
#EXT-X-BYTERANGE:94125@249873
media2.m4s
#EXTINF:4.143333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:55.278Z
#EXT-X-BYTERANGE:148176@343998
media2.m4s
#EXTINF:4.143333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:06:59.421Z
#EXT-X-BYTERANGE:219469@492174
media2.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:07:03.564Z
#EXT-X-BYTERANGE:173242@711643
media2.m4s
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:07:07.664Z
#EXT-X-BYTERANGE:206754@884885
media2.m4s
#EXTINF:10.020000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:07:11.810Z
#EXT-X-BYTERANGE:171670@1091639
media2.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:07:21.830Z
#EXT-X-BYTERANGE:74667@1263309
media2.m4s
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:07:25.930Z
#EXT-X-BYTERANGE:128367@1337976
media2.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:07:30.076Z
#EXT-X-BYTERANGE:180756@1466343
media2.m4s
#EXTINF:4.143333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:07:34.226Z
#EXT-X-BYTERANGE:171579@1647099
media2.m4s
#EXTINF:10.010000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:07:38.369Z
#EXT-X-BYTERANGE:159369@1818678
media2.m4s
#EXTINF:10.006667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:07:48.379Z
#EXT-X-BYTERANGE:98986@1978047
media2.m4s
#EXTINF:9.430000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:07:58.385Z
#EXT-X-BYTERANGE:57302@2077033
media2.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:08:07.815Z
#EXT-X-BYTERANGE:111131@2134335
media2.m4s
#EXTINF:6.200000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:08:11.911Z
#EXT-X-BYTERANGE:94945@2245466
media2.m4s
#EXTINF:4.193333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:08:18.111Z
#EXT-X-BYTERANGE:98154@2340411
media2.m4s
#EXTINF:6.186667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:08:22.304Z
#EXT-X-BYTERANGE:161210@2438565
media2.m4s
#EXTINF:6.200000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:08:28.490Z
#EXT-X-BYTERANGE:113432@2599775
media2.m4s
#EXTINF:5.113333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:08:34.690Z
#EXT-X-BYTERANGE:79246@2713207
media2.m4s
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:08:39.803Z
#EXT-X-BYTERANGE:125344@2792453
media2.m4s
#EXTINF:6.196667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:08:43.949Z
#EXT-X-BYTERANGE:128635@2917797
media2.m4s
#EXTINF:10.013333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:08:50.145Z
#EXT-X-BYTERANGE:60291@3046432
media2.m4s
#EXTINF:4.143333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:00.158Z
#EXT-X-BYTERANGE:85618@3106723
media2.m4s
#EXTINF:6.223333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:04.301Z
#EXT-X-BYTERANGE:128671@3192341
media2.m4s
#EXTINF:6.273333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:10.524Z
#EXT-X-BYTERANGE:82573@3321012
media2.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:16.797Z
#EXT-X-BYTERANGE:154322@3403585
media2.m4s
#EXTINF:4.166667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:20.893Z
#EXT-X-BYTERANGE:163790@3557907
media2.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:25.059Z
#EXT-X-BYTERANGE:126136@3721697
media2.m4s
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:29.159Z
#EXT-X-BYTERANGE:205128@3847833
media2.m4s
#EXTINF:4.173333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:33.305Z
#EXT-X-BYTERANGE:181051@4052961
media2.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:37.478Z
#EXT-X-BYTERANGE:116959@4234012
media2.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:41.578Z
#EXT-X-BYTERANGE:145961@4350971
media2.m4s
#EXTINF:10.013333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:45.728Z
#EXT-X-BYTERANGE:140408@4496932
media2.m4s
#EXTINF:5.010000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:09:55.741Z
#EXT-X-BYTERANGE:79462@4637340
media2.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:00.751Z
#EXT-X-BYTERANGE:179140@4716802
media2.m4s
#EXTINF:6.200000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:04.901Z
#EXT-X-BYTERANGE:139801@4895942
media2.m4s
#EXTINF:6.666667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:11.101Z
#EXT-X-BYTERANGE:77707@5035743
media2.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:17.767Z
#EXT-X-BYTERANGE:168680@5113450
media2.m4s
#EXT-X-DISCONTINUITY
#EXT-X-MAP:URI="media3.m4s",BYTERANGE="880@0"
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:21.917Z
#EXT-X-BYTERANGE:146939@880
media3.m4s
#EXTINF:4.146667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:26.063Z
#EXT-X-BYTERANGE:186183@147819
media3.m4s
#EXTINF:6.190000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:30.209Z
#EXT-X-BYTERANGE:141403@334002
media3.m4s
#EXTINF:5.390000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:36.399Z
#EXT-X-BYTERANGE:166282@475405
media3.m4s
#EXTINF:4.140000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:41.789Z
#EXT-X-BYTERANGE:166852@641687
media3.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:45.929Z
#EXT-X-BYTERANGE:172209@808539
media3.m4s
#EXTINF:8.316667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:50.029Z
#EXT-X-BYTERANGE:91369@980748
media3.m4s
#EXTINF:8.246667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:10:58.345Z
#EXT-X-BYTERANGE:81694@1072117
media3.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:11:06.591Z
#EXT-X-BYTERANGE:102222@1153811
media3.m4s
#EXTINF:9.966667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:11:10.741Z
#EXT-X-BYTERANGE:112478@1256033
media3.m4s
#EXTINF:8.063333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:11:20.707Z
#EXT-X-BYTERANGE:80386@1368511
media3.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:11:28.770Z
#EXT-X-BYTERANGE:125777@1448897
media3.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:11:32.870Z
#EXT-X-BYTERANGE:212424@1574674
media3.m4s
#EXTINF:4.233333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:11:37.020Z
#EXT-X-BYTERANGE:145233@1787098
media3.m4s
#EXTINF:4.090000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:11:41.253Z
#EXT-X-BYTERANGE:169235@1932331
media3.m4s
#EXTINF:4.140000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:11:45.343Z
#EXT-X-BYTERANGE:114699@2101566
media3.m4s
#EXTINF:8.280000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:11:49.483Z
#EXT-X-BYTERANGE:133409@2216265
media3.m4s
#EXTINF:4.140000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:11:57.763Z
#EXT-X-BYTERANGE:100799@2349674
media3.m4s
#EXTINF:4.140000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:01.903Z
#EXT-X-BYTERANGE:134350@2450473
media3.m4s
#EXTINF:9.996667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:06.043Z
#EXT-X-BYTERANGE:182396@2584823
media3.m4s
#EXTINF:5.796667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:16.039Z
#EXT-X-BYTERANGE:73428@2767219
media3.m4s
#EXTINF:3.390000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:21.835Z
#EXT-X-BYTERANGE:40327@2840647
media3.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:25.225Z
#EXT-X-BYTERANGE:228618@2880974
media3.m4s
#EXTINF:4.193333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:29.325Z
#EXT-X-BYTERANGE:155423@3109592
media3.m4s
#EXTINF:6.186667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:33.518Z
#EXT-X-BYTERANGE:135557@3265015
media3.m4s
#EXTINF:5.396667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:39.704Z
#EXT-X-BYTERANGE:102146@3400572
media3.m4s
#EXTINF:10.013333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:45.100Z
#EXT-X-BYTERANGE:141347@3502718
media3.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:55.113Z
#EXT-X-BYTERANGE:118177@3644065
media3.m4s
#EXTINF:6.196667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:12:59.209Z
#EXT-X-BYTERANGE:126276@3762242
media3.m4s
#EXTINF:4.196667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:05.405Z
#EXT-X-BYTERANGE:99218@3888518
media3.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:09.601Z
#EXT-X-BYTERANGE:222384@3987736
media3.m4s
#EXTINF:4.136667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:13.701Z
#EXT-X-BYTERANGE:132081@4210120
media3.m4s
#EXTINF:6.196667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:17.837Z
#EXT-X-BYTERANGE:93709@4342201
media3.m4s
#EXTINF:8.060000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:24.033Z
#EXT-X-BYTERANGE:69447@4435910
media3.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:32.093Z
#EXT-X-BYTERANGE:93280@4505357
media3.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:36.193Z
#EXT-X-BYTERANGE:100396@4598637
media3.m4s
#EXTINF:4.153333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:40.343Z
#EXT-X-BYTERANGE:153662@4699033
media3.m4s
#EXTINF:6.623333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:44.496Z
#EXT-X-BYTERANGE:163084@4852695
media3.m4s
#EXTINF:4.096667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:51.119Z
#EXT-X-BYTERANGE:150143@5015779
media3.m4s
#EXTINF:6.240000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:13:55.215Z
#EXT-X-BYTERANGE:106699@5165922
media3.m4s
#EXT-X-DISCONTINUITY
#EXT-X-MAP:URI="media4.m4s",BYTERANGE="880@0"
#EXTINF:4.140000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:14:01.455Z
#EXT-X-BYTERANGE:134346@880
media4.m4s
#EXTINF:4.143333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:14:05.595Z
#EXT-X-BYTERANGE:129717@135226
media4.m4s
#EXTINF:6.373333,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:14:09.738Z
#EXT-X-BYTERANGE:70901@264943
media4.m4s
#EXTINF:4.100000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:14:16.111Z
#EXT-X-BYTERANGE:187161@335844
media4.m4s
#EXTINF:4.150000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:14:20.211Z
#EXT-X-BYTERANGE:169533@523005
media4.m4s
#EXTINF:6.240000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:14:24.361Z
#EXT-X-BYTERANGE:91256@692538
media4.m4s
#EXTINF:6.186667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:14:30.601Z
#EXT-X-BYTERANGE:89550@783794
media4.m4s
#EXTINF:7.280000,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:14:36.787Z
#EXT-X-BYTERANGE:128166@873344
media4.m4s
#EXTINF:8.266667,
#EXT-X-PROGRAM-DATE-TIME:2025-01-14T05:14:44.067Z
#EXT-X-BYTERANGE:144445@1001510
media4.m4s
#EXT-X-ENDLIST

import { FFmpeg } from '@ffmpeg/ffmpeg';

const ffmpeg = new FFmpeg();
export default class VideoConverter {
  constructor() {
    this.initialized = false;
    this.ffmpeg = null;
    this.videoResolution = '1280x720';
    this.isHD = false;
  }

  static downloadFile(data, filename) {
    const blob = new Blob([data], { type: 'video/mp4' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    a.click();
    URL.revokeObjectURL(url);
  }

  async initialize() {
    if (!this.initialized) {
      try {
        await ffmpeg.load();
        this.ffmpeg = ffmpeg;
        this.initialized = true;
        this.ffmpeg.on('progress', (data) => {
          console.log(data);
        });
      } catch (error) {
        throw new Error(`FFmpeg initialization failed: ${error.message}`);
      }
    }
  }

  parseM3U8(m3u8Text) {
    const lines = m3u8Text.trim().split('\n');
    const mediaFiles = new Set();

    const initFile = lines.find((line) => line.includes('#EXT-X-MAP:'));
    this.isHD = lines.find((line) => line.includes('#EXT-X-SESSION-DATA:DATA-ID="hdresolution"'));
    if (this.isHD) {
      const match = this.isHD.match(/VALUE="([^"]+)"/);
      if (match) {
        this.videoResolution = match[1].replace(/x/g, ':');
      }
    }
    if (initFile) {
      const match = initFile.match(/URI="([^"]+)"/);
      if (match) {
        mediaFiles.add(match[1]);
      }
    }

    lines.forEach((line) => {
      if (!line.startsWith('#') && line.trim()) {
        mediaFiles.add(line.trim());
      }
    });

    return Array.from(mediaFiles);
  }

  static async fetch(url, options) {
    const response = await fetch(url, options);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response;
  }

  static getFileExtension(filename) {
    const match = filename.match(/\.([^.]+)$/);
    return match ? match[1].toLowerCase() : 'ts';
  }

  static async downloadMediaFiles(baseUrl, mediaFiles) {
    const fileBuffers = new Map();
    const chunks = VideoConverter.chunkArray(Array.from(mediaFiles), 5);

    await chunks.reduce(async (previousChunk, chunk) => {
      await previousChunk;
      return Promise.all(
        chunk.map(async (mediaFile) => {
          try {
            const fileUrl = baseUrl + mediaFile;
            const response = await VideoConverter.fetchTs(fileUrl, {
              credentials: 'include',
              headers: { Cookie: document.cookie },
            });
            const data = await response.arrayBuffer();
            fileBuffers.set(mediaFile, new Uint8Array(data));
          } catch (error) {
            console.error(`Failed to download ${mediaFile}:`, error);
            throw error;
          }
        }),
      );
    }, Promise.resolve());

    return fileBuffers;
  }

  static chunkArray(array, size) {
    const chunks = [];
    for (let i = 0; i < array.length; i += size) {
      chunks.push(array.slice(i, i + size));
    }
    return chunks;
  }

  async convertM3U8ToMP4(m3u8Url, outputFilename, progressCallback = null) {
    console.time('convertM3U8ToMP4_Total_Time');
    const startTime = performance.now();

    try {
      await this.initialize();

      const m3u8Response = await VideoConverter.fetch(m3u8Url, {
        credentials: 'include',
        headers: { Cookie: document.cookie },
      });
      const m3u8Text = await m3u8Response.text();
      const baseUrl = m3u8Url.substring(0, m3u8Url.lastIndexOf('/') + 1);
      await this.ffmpeg.writeFile('input.m3u8', m3u8Text);

      const mediaFiles = this.parseM3U8(m3u8Text);

      if (progressCallback) {
        progressCallback(0.2, 'start download files');
      }
      const fileBuffers = await VideoConverter.downloadMediaFiles(baseUrl, mediaFiles);

      await fileBuffers.entries().forEach(async ([fileName, data]) => {
        await this.ffmpeg.writeFile(fileName, data);
      });

      const args = ['-i', 'input.m3u8'];
      if (this.isHD) {
        args.push('-c:v', 'libx264');
        args.push('-preset', 'ultrafast');
        args.push('-c:a', 'aac');
        args.push('-vf', `scale=${this.videoResolution},setsar=1:1`);
      } else {
        args.push('-c', 'copy');
      }
      args.push(outputFilename);

      // download
      if (progressCallback) {
        progressCallback(0.9, 'ready to download');
      }

      await this.ffmpeg.exec(args);

      const data = await this.ffmpeg.readFile(outputFilename); // mp4
      VideoConverter.downloadFile(data, outputFilename);

      const endTime = performance.now();
      console.timeEnd('convertM3U8ToMP4_Total_Time');
      console.log(`Total execution time: ${(endTime - startTime).toFixed(2)}ms`);

      if (progressCallback) {
        progressCallback(1, 'finish');
      }
    } catch (error) {
      console.error('Conversion failed:', error);
      throw error;
    }
  }
}

// example
// const converter = new VideoConverter();
// converter.convertM3U8ToMP4(
//   'm3u8Url',
//   'output.mp4',
//   (progress, status) => console.log(`${(progress * 100).toFixed(1)}%: ${status}`)
// );

Expected behavior
The expected behavior is to successfully convert the M3U8 playlist containing .m4s segments into a complete MP4 file, similar to how an M3U8 playlist with .ts segments can be converted.

Desktop (please complete the following information):

  • OS: [Apple M3]
  • Browser [chrome]
  • Version [131.0.6778.265]

I can see problem in your implementation. this part:

await fileBuffers.entries().forEach(async ([fileName, data]) => {
        await this.ffmpeg.writeFile(fileName, data);
      });

You cant combine foreach with async. its just wrong.