1

I want to play a video (mp4) with libvlcsharp using C# in WinForms.

I load the media using a Stream because the file will be encrypted and I will then manage to decrypt it before loading it in the media object.

I succeeded loading and playing the video, but I am failing to Parse it.

I want to Parse it in order to be able to get information such as Duration, AudioChannels, FrameRate, Width, etc. before playing it.

I call Parse (tried with every combination of options), the IsParsed property changes to True but the ParsedStatus is not Done but Skipped.

If I load the file directly (without using a srtream) it parses ok.

My code:

Stream contentStream = System.IO.File.Open("c:\test\test.mp4" , System.IO.FileMode.Open);
                                                                
Media Video = new Media(utils.GetLibVLC(), new StreamMediaInput(contentStream));

Video.Parse(MediaParseOptions.ParseLocal | MediaParseOptions.ParseNetwork);

while (!Video.IsParsed)  
    System.Threading.Thread.Sleep(50);
                        
if (Video.ParsedStatus == MediaParsedStatus.Done)   //Video.ParsedStatus equals to Skipped
{
    long Duration = Video.Duration;

    foreach (MediaTrack track in Video.Tracks)
    {
        switch (track.TrackType)
        {
            case TrackType.Audio:
                int AudioChannels = (int)track.Data.Audio.Channels;
                int AudioRate = (int)track.Data.Audio.Rate;
                break;
            case TrackType.Video:
                float FrameRate = track.Data.Video.FrameRateNum / track.Data.Video.FrameRateDen;
                int Width = (int)track.Data.Video.Width;
                int Height = (int)track.Data.Video.Height;
                float Ratio = (float)Width / Height;
                break;
        }
    }                            
}

(I know the while is dangerous I will improve it later).

Does anybody know how to parse a video loaded through a stream?

MundoPeter
  • 704
  • 6
  • 12
  • https://github.com/oaubert/python-vlc/issues/81 – Hans Passant Nov 30 '20 at 00:34
  • @HansPassant Thank you for the answer but the link says to use "parse_with_options" and listend the the event libvlc_MediaParsedChanged. There is not such a method "parse_with_options", but since the description and parameters of "Parse" are coincident with "parse_with_options", I think it must be the right method. I listend to the event, it gets fired but it keeps saying Skipped and the properies are not set. – MundoPeter Nov 30 '20 at 00:52
  • @MundoPeter You can't play encrypted stream easily. Developers have created wrapper for it. See example https://github.com/footballs/libvlcsharp-encrypted-stream – Sorry IwontTell Nov 30 '20 at 05:03
  • https://goldeneye2.videolan.org/videolan/LibVLCSharp/-/issues/388 – Sorry IwontTell Nov 30 '20 at 05:05
  • Please attach some verbose logs (see the troubleshooting section of the repo). The behavior you're seeing is likely cause by libvlc itself. – cube45 Nov 30 '20 at 06:22
  • @SorryIwontTell The problem is not with encryption. The stream I am using is not encrypted yet, I am trying lo load media from stream first, and it does not Parse it. – MundoPeter Nov 30 '20 at 17:16
  • @cube45 I set "--verbose=2" but nothing is loged when I execute Parse. MediaParsedChanged event is fired with Status==Skipped. Later, when I then execute Play, the MediaParsedChanged event fires again, now with Status==Done and It generates a lot of log. But it generates no log when I call Parse which is what I want to solve. – MundoPeter Nov 30 '20 at 17:21
  • @MundoPeter also tell player where to put log file. Sounds like http://github.com/oaubert/python-vlc/issues/81#issuecomment-480511121. Maintainers always helped me https://discord.com/invite/3h3K3JF – Sorry IwontTell Nov 30 '20 at 17:41
  • Please paste your full logs in a pastebin so we can have a look. – cube45 Nov 30 '20 at 21:18
  • I see here that Parse is actually an async method you could await : https://code.videolan.org/videolan/LibVLCSharp/-/blob/3.x/src/LibVLCSharp/Shared/Media.cs#L447 Why not `var status = await Video.Parse(MediaParseOptions.ParseLocal | MediaParseOptions.ParseNetwork);` then ? – cube45 Nov 30 '20 at 21:24

2 Answers2

2

My explanation would be that it is not supported.

I've seen this line of code : https://code.videolan.org/videolan/vlc/-/blob/a4ca0de9e087e6a6a3bb86c585cf29ad5c553576/src/preparser/preparser.c#L362 , which seems to mean that the parsing is skipped if it's not a network nor a file.

You could raise the issue on videolan's bugtracker if you want this feature.

cube45
  • 3,429
  • 2
  • 24
  • 35
0

did you try this ?

var parseStatusTask = Task.Run(async () => await Video.Parse(MediaParseOptions.ParseNetwork));
parseStatusTask.Wait();
Eric
  • 1
  • Now I did, but it does not work either. Which is not surprise since the problem is not with waiting but with VLC skipping the parse of streams. – MundoPeter Mar 27 '21 at 20:21