0

Hi
I need to stream a video file and save it using LIBVLC. Here is what I have done so far:

libvlc_media_t* vlcMedia = nullptr;
libvlc_instance_t* vlcInstance = libvlc_new(0, nullptr);
vlcMedia = libvlc_media_new_location(vlcInstance, aUri);
if(nullptr != vlcMedia)
{
    libvlc_media_player_t* vlcMediaPlayer = libvlc_media_player_new_from_media(vlcMedia);
    if(nullptr != vlcMediaPlayer)
    {
        libvlc_media_release(vlcMedia);
        libvlc_event_manager_t* vlcMediaManager = libvlc_media_player_event_manager(vlcMediaPlayer);
        if(nullptr != vlcMediaManager)
            libvlc_event_attach(vlcMediaManager, libvlc_MediaPlayerEndReached, OnStopped, this);
        libvlc_media_player_set_hwnd(vlcMediaPlayer, Handle);
        libvlc_media_player_play(vlcMediaPlayer);
    }
}

This will connect to the remote media and starts playing the video. The question is how do I direct it to save the video? I could not find the API call for that.

Thank you
Sam

Thanks to @mtz the solution is to add:

libvlc_media_add_option(vlcMedia,":sout=#duplicate{dst=display,dst=std{access=file,mux=mp4,dst=xyz.mp4}");

after the call to libvlc_media_new_location.

Sam
  • 2,473
  • 3
  • 18
  • 29
  • Possible duplicate of [Saving a stream while playing it using LibVLC](https://stackoverflow.com/questions/16515099/saving-a-stream-while-playing-it-using-libvlc) – avariant Mar 22 '19 at 19:13
  • @avariant I am not using python and also I'm not getting the media from HTTP. The media hat I'm connecting to is being multicasted using RTSP and where I need to save the file might have the full path like "C:\Users\a_user\Videos\test 1\myVideo.mpg". Notice that path has a blank in it. – Sam Mar 22 '19 at 19:30
  • 1
    The commands and techniques are identical, however, despite the language. Take a careful look at djf's answer using "duplicate", "transcode", and the "file" destination. (Also Maresh's answer which has a c version.) That is the key to saving a streaming media to disk. I use the exact same technique with the c++ library. And if your path has spaces, you can escape it with quotes. – avariant Mar 22 '19 at 20:32
  • @avariant I tried it and it does not work. The output file is never created. Also the documentation for [libvlc_new](https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__core.html#ga915aa5778053d7b52ff9f6ba6e2f7764) clearly states `argc` has to be 0 and `argv` has to be `NULL`. In any case @mtz answer worked much better. Thanks – Sam Mar 25 '19 at 19:04

2 Answers2

3

Here's a C# version that you can easily adapt to C/C++

var currentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var destination = Path.Combine(currentDirectory, "record.ts");

// Load native libvlc library
Core.Initialize();

using (var libvlc = new LibVLC())
using (var mediaPlayer = new MediaPlayer(libvlc))
{
    // Redirect log output to the console
    libvlc.Log += (sender, e) => Console.WriteLine($"[{e.Level}] {e.Module}:{e.Message}");

    // Create new media with HLS link
    var media = new Media(libvlc, "http://hls1.addictradio.net/addictrock_aac_hls/playlist.m3u8", FromType.FromLocation);

    // Define stream output options. 
    // In this case stream to a file with the given path and play locally the stream while streaming it.
    media.AddOption(":sout=#file{dst=" + destination + "}");
    media.AddOption(":sout-keep");

    // Start recording
    mediaPlayer.Play(media);

    Console.WriteLine($"Recording in {destination}");
    Console.WriteLine("Press any key to exit");
    Console.ReadKey();
}
mfkl
  • 1,914
  • 1
  • 11
  • 21
  • Thank you, this worked much better, but the video file that is created is very choppy (plays for about 1 second and pauses 8 or 9 second then jumps to another scene and repeats). Here is how I made it work: `libvlc_media_add_option(vlcMedia,":sout=#duplicate{dst=display,dst=std{access=file,mux=ps,dst=xyz.mpg}");` – Sam Mar 25 '19 at 19:13
0

Might anyone know the syntax to merge two files (of identical format, etc.?) The 'sout' options I have already and know they work from the command line, but incorporating the filenames is where I'm not having success. eg: the command line call would be:

./vlc.exe ./chunk1.mp4 ./chunk2.mp4 ./chunk3.mp4 --sout "#gather:std{access=file,mux=mp4,dst=c:\\users\\user\\desktop\\myfile.mp4}" --no-sout-all --sout-keep

using AddOption() for the "--sout.." options seems the way to go, but using AddOption() for the filenames isn't working (the output file is created, but it's empty besides a header. Thanks!

MBR
  • 1
  • If you have a new question, please ask it by clicking the [Ask Question](https://stackoverflow.com/questions/ask) button. Include a link to this question if it helps provide context. - [From Review](/review/late-answers/34641374) – BoP Jul 07 '23 at 18:25