mpv-player / mpv

🎥 Command line video player
https://mpv.io
Other
28.02k stars 2.88k forks source link

MPV can't play non-standard M3U8 stream with faked video parts as 1x1 pixel images #11365

Open GunGunGun opened 1 year ago

GunGunGun commented 1 year ago

Important Information

Provide following Information:

If you're not using git master or the latest release, update. Releases are listed here: https://github.com/mpv-player/mpv/releases

Reproduction steps

Note: Requires setting Referer header to bypass anti-hotlinking.

Command: mpv --no-ytdl --no-config --log-file=mpv.log "https://hls.anime47.com/m3u8/0cd7f99b84d0ff355a6f6c29f73316c0.m3u8" --http-header-fields="Referer: https://anime47.com/"

Can't play video because M3U8's parts are non-standard and faked as 1x1 pixel image but web browser and Streamlink can, for example using Streamlink to open above M3U8 link will make it playable, but MPV alone doesn't: streamlink.exe https://hls.anime47.com/m3u8/0cd7f99b84d0ff355a6f6c29f73316c0.m3u8 480p,best --http-header Referer=https://anime47.com/ --stream-segment-threads=3 --stream-segment-timeout 35.00 --http-no-ssl-verify --twitch-disable-ads --player-no-close --player=D:\mpv\mpv.exe

Expected behavior

MPV should be able to play above link.

Actual behavior

MPV can't and this is error log:

[ffmpeg/demuxer] image2: Custom AVIOContext makes no sense and will be ignored with AVFMT_NOFILE format.
[ffmpeg/demuxer] hls: Could not find codec parameters for stream 0 (Video: png, none(pc)): unspecified size
[ffmpeg/demuxer] Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
 (+) Video --vid=1 (png)
[lavf] error reading packet: Invalid argument.
[lavf] error reading packet: Invalid argument.
[lavf] error reading packet: Invalid argument.
[lavf] error reading packet: Invalid argument.
[lavf] error reading packet: Invalid argument.
[lavf] error reading packet: Invalid argument.
[lavf] error reading packet: Invalid argument.
[lavf] error reading packet: Invalid argument.
[lavf] error reading packet: Invalid argument.
[lavf] error reading packet: Invalid argument.
[lavf] error reading packet: Invalid argument.
[lavf] ...treating it as fatal error.

Exiting... (Errors when loading file)

Log file

See attachment: mpv.log

Sample files

mpv --no-ytdl --no-config --log-file=mpv.log "https://hls.anime47.com/m3u8/0cd7f99b84d0ff355a6f6c29f73316c0.m3u8" --http-header-fields="Referer: https://anime47.com/"

Don't try to remove --http-header-fields="Referer: https://anime47.com/" because that will never work and trigger anti-hotlinking redirect to www.cloudflare.com.

xfangfang commented 1 year ago

I have encountered similar problems before, which can be solved by modifying the ffmpeg code to force the hls ts type. This is a simple patch:https://github.com/xfangfang/FFmpeg/commit/b2363997fd89da8f43eb557b59f6f2fa263770b1

I don't think this is a issue that mpv or ffmpeg need to solve, because such videos are non-standard, and most of them are used by pirated video websites to save their own traffic.

GunGunGun commented 1 year ago

I have encountered similar problems before, which can be solved by modifying the ffmpeg code to force the hls ts type. This is a simple patch:xfangfang/FFmpeg@b236399

I don't think this is a issue that mpv or ffmpeg need to solve, because such videos are non-standard, and most of them are used by pirated video websites to save their own traffic.

Thank you very much!! Yeah I agree about that, but I would still like to be able to solve most video formats because I mainly use MPV to watch online video (using Firefox's userscript to send video link to MPV), would be great if MPV/FFMPEG just ignore broken video format and play them anyways.

Can you submit this patch to official FFMPEG, would be great if they accept your commit because IIRC VLC ignores a lot of broken video formats, they play even corrupted videos.

I can live without that tho because Streamlink somehow can force MPV to play above M3U8 link.

xfangfang commented 1 year ago

I don't know much about the hls format. Maybe forcing a certain format will cause some videos in the correct format to fail to play, so I don't think ffmpeg will accept my patch. (If you are interested to make a pr, you can try. feel free to use that patch code.)

As a workaround, you can compile ffmpeg based on the above simple patch, and then compile mpv based on this ffmpeg.

Another solution may be to parse the m3u8 file and convert all the links in it to the edl link form of mpv. In this way, video can be played continuously by forcing the decoding format of mpv. However, I haven't tested whether it can be used. It's just a temporary idea that come to my mind now.

https://github.com/mpv-player/mpv/blob/master/DOCS/edl-mpv.rst

GunGunGun commented 1 year ago

I don't know much about the hls format. Maybe forcing a certain format will cause some videos in the correct format to fail to play, so I don't think ffmpeg will accept my patch. (If you are interested to make a pr, you can try. feel free to use that patch code.)

As a workaround, you can compile ffmpeg based on the above simple patch, and then compile mpv based on this ffmpeg.

Another solution may be to parse the m3u8 file and convert all the links in it to the edl link form of mpv. In this way, video can be played continuously by forcing the decoding format of mpv. However, I haven't tested whether it can be used. It's just a temporary idea that come to my mind now.

https://github.com/mpv-player/mpv/blob/master/DOCS/edl-mpv.rst

I see, I'll try the parse method and see, at least it looks a bit simpler for me to do in batch and use daily. At least parsing text file is something I'm comfortable with, at first I was thinking about parsing broken faked video parts and delete fake headers and only send working stuffs to client (in this case MPV) using my transparent proxy server like Burp Suite, literally just proxy everything from MPV to a local transparent proxy server and change whatever I want to change from there.

stumpedatwork commented 1 year ago

I have seem a sample of this file where a PNG is prepended to a MPEGTS segment. I assume the PNG is a preview for the segment. Can I know what web video player is using this kind of files ?

xfangfang commented 1 year ago

@stumpedatwork It's not a preview, It pretend mpegts as a png, then they (pirated video websites) uploads this kind of “png” to public cdn to save their own traffic.

GunGunGun commented 1 year ago

I have seem a sample of this file where a PNG is prepended to a MPEGTS segment. I assume the PNG is a preview for the segment. Can I know what web video player is using this kind of files ?

I currently found my own solution to use a intercept proxy like Burpsuite to remove PNG header from faked video parts and that way MPV can play normally, this is my demo: https://streamable.com/kl7poc

It works, but it's super complicated.

po5 commented 4 weeks ago

According to #14781 the solution looks like this: https://code.videolan.org/videolan/vlc/-/merge_requests/5934

kasper93 commented 4 weeks ago

The solution is simple enough, but it has to be implemented on ffmpeg side, as mpv doesn't process HLS playlists itself. Feel free to send a patch or an issue to ffmpeg.

GalaxySnail commented 4 weeks ago

If I understand correctly, before it's fixed in ffmpeg, there may be a workaround: yhdm_proxy. Disclaimer: I'm the author, but it was a quick hack and I haven't used it in the past 2 years.