Yet another video capture / recording question

This forum is about all development around libVLC.
wrybread
Blank Cone
Blank Cone
Posts: 17
Joined: 24 Mar 2007 05:44

Yet another video capture / recording question

Postby wrybread » 23 Oct 2018 22:32

[Edited to add: oops, @Moriquendi posted almost exactly the same question while I was writing this. It's here fyi: https://forum.videolan.org/viewtopic.ph ... 8&p=481599. I'll leave this up in hopes that it helps us solve the problem]

I've read through all the threads on recording video streams using libVLC, but still can't figure out how to start recording without re-initting the stream. In other words, to smoothly start recording when I click a record button without having to restart playback. The VLC GUI does what I want, when I right-click a video and press the "record" button.

I'm using the Python bindings (vlc.py), and I can record by initting the player like this:

Code: Select all

options = "--sout=#duplicate{dst=std{access=file,dst='output.mp4'},dst=display}" vlcInstance = vlc.Instance(options) player = vlcInstance.media_player_new() media1 = vlcInstance.media_new(unicode('whatever.mp4')) player.set_media(media1) player.play()
This will play the file whatever.mp4 and save it to output.mp4.

But my problem is: if I init the player without the --sout options, and simply play the file, how do I start recording?

I'm making an app to play an IP camera (RTSP), and reinitting the stream causes a lot of flicker while it buffers so it's important not to reinit if possible.

I made a stripped down sample app in wxPython if anyone wants to have a look:

Code: Select all

#! /usr/bin/python import os, sys, time import wx # at least 2.8 I think import vlc current_directory = os.path.dirname(os.path.realpath(__file__)) class Player(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, "VLC Test", pos=wx.DefaultPosition, size=(850, 560)) self.program_launch_time = time.time() self.video_initted = False self.Bind(wx.EVT_CLOSE, self.onExit) # Video panel self.videopanel = wx.Panel(self, -1, style= wx.WANTS_CHARS) # The second panel holds controls self.ctrlpanel = wx.Panel(self, -1, style= wx.WANTS_CHARS ) # Buttons self.button1 = wx.Button(self.ctrlpanel, label="Record") self.button1.Bind(wx.EVT_LEFT_DOWN, self.onRecord) self.screenshot = wx.Button(self.ctrlpanel, label="Screenshot") self.screenshot.Bind(wx.EVT_LEFT_DOWN, self.onGetScreenshot) # Give a pretty layout to the controls self.ctrlbox = wx.BoxSizer(wx.VERTICAL) self.box2 = wx.BoxSizer(wx.HORIZONTAL) self.box2.Add((-1, -1), 1) self.box2.Add(self.button1) self.box2.Add(self.screenshot) self.box2.Add((-1, -1), 1) # Merge box1 and box2 to the ctrlsizer self.ctrlbox.Add(self.box2, 1, wx.EXPAND) self.ctrlpanel.SetSizer(self.ctrlbox) # Put everything togheter self.sizer2 = wx.BoxSizer(wx.VERTICAL) self.sizer2.Add(self.videopanel, 1, flag=wx.EXPAND) self.sizer2.Add(self.ctrlpanel, flag=wx.EXPAND | wx.BOTTOM | wx.TOP, border=10) self.SetSizer(self.sizer2) self.SetMinSize((600, 400)) # finally create the timer. self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.onTimer, self.timer) self.timer.Start(50) # VLC player controls options = "" options += "--sub-source marq " # enable the marquee printing options += "--no-video-title " # not sure if does anything options += "--verbose=2 " # lots of output (-1 is no output) # record the output #options += "--sout=#duplicate{dst=std{access=file,mux=mp4,dst='%s'},dst=display} " % os.path.abspath(current_directory + "/output.mp4") self.vlcInstance = vlc.Instance(options) # this lets me write to the VLC marquee... self.player = self.vlcInstance.media_player_new() def onGetScreenshot(self, event): timestamp = time.strftime("%Y-%m-%d_%H-%M-%S") fname = os.path.abspath(current_directory + "/snapshots/%s.png" % timestamp) try: os.makedirs(os.path.dirname(fname) ) except: pass result = self.player.video_take_snapshot(0, fname, 0, 0) print "Snapshot saved to %s" % fname return def onRecord(self, evt): print "start recording!" # if I init with these options, it records. How to start recording without restarting video? #options += "--sout=#duplicate{dst=std{access=file,mux=mp4,dst='%s'},dst=display} " % os.path.abspath(current_directory + "/output.mp4") def onPlay(self, evt): self.video_path = os.path.join(current_directory, "test.mp4") self.Media = self.vlcInstance.media_new(unicode(self.video_path), "no-video-title", ) self.player.set_media(self.Media) # set the window id to render VLC's video output handle = self.videopanel.GetHandle() if sys.platform.startswith('linux'): self.player.set_xwindow(handle) elif sys.platform == "darwin": self.player.set_nsobject(handle) else: self.player.set_hwnd(handle) self.player.play() return def onTimer(self, event): # on Ubuntu, if I init the video right away it launches in a separate window. # Prob a good idea to let other things init first anyway if (time.time() - self.program_launch_time > 1) and not self.video_initted: self.video_initted=True self.onPlay(None) def onExit(self, evt): os._exit(1) if __name__ == "__main__": app = wx.PySimpleApp() player = Player() player.Centre() player.Show() app.MainLoop()
Can download the above zipped with the sample video here gizmoware.net/dropbox/simpleplayer.zip.

I don't imagine anyone has any hints?

mfkl
Developer
Developer
Posts: 727
Joined: 13 Jun 2017 10:41

Re: Yet another video capture / recording question

Postby mfkl » 29 Oct 2018 03:57

Hey,

I tried doing this as well recently and it turns out this is not currently supported by vanilla libvlc 3. You will need to patch.

An alternative way I've been suggested is to use an additional mediaplayer in the background which only does sout (no display).
https://mfkl.github.io

Moriquendi
Blank Cone
Blank Cone
Posts: 74
Joined: 31 May 2011 16:22

Re: Yet another video capture / recording question

Postby Moriquendi » 31 Oct 2018 15:17

Hey wrybread,

I kinda solved this. You can check my solution on https://forum.videolan.org/viewtopic.php?f=32&t=146788

Basically you need pcap library in combination with a single VLC instance. Use VLC instance just to display the media, and bind pcap udp socket to the incoming media stream port. (same as VLC input port. My input source was a network stream, so this only works if the same goes for you). My input source and my recording format are both transport stream. So all I had to do is write the payload of the incoming packets into a file. Make sure you dont skip any packets and you should be fine.


Return to “Development around libVLC”

Who is online

Users browsing this forum: Google [Bot] and 6 guests