ffmpeginteropx / FFmpegInteropX

FFmpeg decoding library for Windows 10 UWP and WinUI 3 Apps
Apache License 2.0
212 stars 53 forks source link

Error using MediaSourceConfig in WindowsAppSDK #330

Closed BlameTwo closed 1 year ago

BlameTwo commented 2 years ago

The following errors occurred when I used MediaSourceConfig in today's test The type initializer for 'WinRT.ActivationFactory`1' threw an exception.

code:

MediaSourceConfig Config = new MediaSourceConfig();
Config.FFmpegOptions.Add("referer", "https://www.bilibili.com");
Config.FFmpegOptions.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36");
var value2 = await FFmpegInteropX.FFmpegMediaSource.CreateFromUriAsync(item.BaseUrl, Config) ;
var mediaSource = value2.CreateMediaPlaybackItem();
NowMediaPlayer.Source = mediaSource;

This error occurred when initializing Config. Is there a solution?

lukasf commented 1 year ago

For this to work with WinRT, you need to add the CsWinRT Nuget package, and you must run it as a "Packaged" app. If you want to run unpackaged, you need to add VCRTForwarders.140 as well.

Oh and you must add FFmpegInteropX as Nuget package. If you add it as project reference, the dll is not moved to the correct location, which also leads to ActivationFactory exceptions.

BlameTwo commented 1 year ago

I executed as you did. MediaSource has no problem, but after calling CreateFromUriAsync Error HRESULT E_ FAIL has been returned from a call to a COM component. I don't know what to do next.

微信截图_20221201085646

brabebhin commented 1 year ago

Can you provide a repo sample?

BlameTwo commented 1 year ago

App2.zip This is an instance, which contains an API interface library. Here it is BIlibiliAccount, which is still the problem above. I can only use the Microsoft Dash configuration file now.

BlameTwo commented 1 year ago

I'm not sure if it's my Nuget package reference error

lukasf commented 1 year ago

Frankly, I have not yet run the sample, but I think this is a normal error, because the URL you are passing is not a valid stream. Try copying the URL and pasting it in one of our CS or CPP sample apps. The samples (except WinUI sample) have ffmpeg logging enabled and will show output messages starting with "FFmpeg" in the debug output window. Then you will see what the error reason is. Alternatively, you can try to open an URL with ffplay (which is usually part of public ffmpeg builds). If gives detailed log output. If an URL cannot be played with ffplay, you cannot play it thorugh our lib.

It looks like you are trying to manually play DASH substreams, which is a really difficult task. I have some experience with that. In the DASH format, every stream is divided into separate substreams (multiple video and audio streams with different bitrate), and each of these substreams is again split into thousands of segments, each only few seconds long. The segments cannot be played individually, because they do not contain any stream info / header data. The header data is contained in an initialization segment, which must be prepended to the segments when you try to decode the stream.

The central part of a DASH stream is the MDP file, which defines the streams, the init segments, the segment sizes, a base url and a template from which to generate the segment file names (usually containing the segment number or timestamp). If you can find the path to the MDP header, you can open that with FFmpegInteropX and it should allow playback, including all substreams. But trying this manually is very difficult. You'd need to find out the segment name template (I do not see that in the API model). You have to find out the init segment url and connect init segment and content segments as one stream (I am not even sure if that is currently possible from our lib). You have to play both the video and audio stream in sync. You will need to support seeking.

Instead of trying to do this manually, I'd recommend you try to find out how to get the path of the MDP file for a video. I am pretty sure there is one. If this Bidi system has a website for video playback, you could open the broswer developer tools (F12), open the network tab and select "media". Then open the same movie you try to play via API, and look at which URLs are opened. You should hopefully see the MDP file and then lots of m4a segments being opened during playback. Maybe you can find a way to reconstruct the MDP path from a movie ID and/or some of the data you get from the REST API.

What could make things worse is if the system requires some sort of authorization. It might be that you'd need to set certain auth headers or cookies to allow playback. Just saying, because when I open the URL which is at the bottom of the MainPage.cs, I get an error 403 (not allowed). So there can be additional roadblocks.

BlameTwo commented 1 year ago

Yes, he has a security chain and needs to specify the referer as the homepage of his website. I'm trying to use the mpd file