锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++开源 | C#开源 / VLC串流相关技术答疑和VLC流数据捕获细节指导
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

用IMemoryInputMedia串流文件内的图片

How to stream IMemoryInputMedia怎样实现IMemoryInputMedia的串流

golchen

16-Jun-15 7:19 

Hi,

I want IMemoryInputMedia to stream bitmaps read from files. My code list below:我想用IMemoryInputMedia串流文件内的图片。代码如下:


StreamInfo fInfo = new StreamInfo();
fInfo.Codec = VideoCodecs.BGR24;
fInfo.Category = StreamCategory.Video;
fInfo.FPS = (int)FrameRate;
fInfo.Width = bmp.Width;
fInfo.Height = bmp.Height;
fInfo.Size = bmp.Width * bmp.Height * 3;

media = m_factory.CreateMedia<IMemoryInputMedia>(MediaStrings.IMEM, new string[]{});
media.Initialize(fInfo, 30);


IVideoPlayer player = m_factory.CreatePlayer<IVideoPlayer>();
player.WindowHandle = panel1.Handle;
player.Open(media);
player.Play();


The frame data is added in a timer event:桢数据用定时器事件添加


int frameNumber = 0;
Font font = new Font("Tahoma", 10);
private void timer1_Tick(object sender, EventArgs e)
{
//to get bitmap somewhere
Bitmap bmp = (Bitmap)Bitmap.FromFile(@"c:\temp\2del.bmp");
frameNumber++;
long frameIntervalInMicroSeconds = 1000000 / FrameRate;
long PTS = ++frameNumber * frameIntervalInMicroSeconds;
media.AddFrame(bmp , PTS);
}

The stream can successfully display in panel1, but I actually want to steam it as rtsp, so I added next option to create the media:串流能正常显示到panel里,但是想用RTSP协议串流,所以加上如下代码来创建媒体:
string[] options = {                   ":sout=#transcode{vcodec=h264,acodec=none}:rtp{sdp=rtsp://:8080/cg.sdp",  ":sout-keep" };
media = m_factory.CreateMedia(MediaStrings.IMEM, options);

Then I tried to open the rtsp stream in VLC player.It failed with message:打开rtsp流失败,提示:
Your input can't be opened:
VLC is unable to open the MRL 'rtsp://localhost:8080/cg.sdp'. Check the log for details.不能打开MRL,请检查日志。

I was wondering is it possible to stream a series of bitmaps? Can anyone help me please? 想串流一系列图片可行不?
Thank you,

GC

Reply·Email·View Thread·Permalink·Bookmark

Re: How to stream IMemoryInputMedia

golchen

17-Jun-15 5:08 

Problem solved. It failed because the image width/height cannot divided by 2.因为宽高不能除以2.

libVLC 1.2.0串流参数

Hello Milos,

the following code works with libVLC 1.2.0 dlls:
Hide   Copy Code


string output = @":sout=#transcode{vcodec=h264,vb=384,fps=20,width=320,height=200,acodec=mp4a,ab=128,channels=2,samplerate=44100}:udp{mux=ts,dst=127.0.0.1:1234}";
IMediaPlayerFactory factory = new MediaPlayerFactory();
IPlayer player = factory.CreatePlayer<IPlayer>();
IScreenCaptureMedia media = factory.CreateMedia<IScreenCaptureMedia>(MediaStrings.SCREEN, output);
media.FPS = 10;
player.Open(media);
player.Play();


Note that IScreenCaptureMedia object has some properties like frame per second and capture area of the screen.

After running this open VLC and select open network stream udp://@127.0.0.1:1234

Roman

64位下不太正常

64bit Streaming intermittent, 32bit works fine 64位环境下断断续续,32位正常

WeseleWang

12-Nov-13 3:53 

Hi Roman,

The lib is fantastic! I am using the memory input/output and streaming as RTSP, everything is great on 32bit system, but when compiled as 64bit program, the streaming looks intermittent, and try to check the code, the callback OnImemGet comes irregularly (32bit comes regularly in about 40ms/time).
检查代码后,OnImemGet回调触发不规则(32位规则调用40ms一次)
I tried 2.0.6, 2.0.7, 2.1.0, they are all same, whatever the video source, whatever the codec, whatever the streaming method....32bit fine, 64bit odd. please help! appreciated.

Besides, play videos, both 32/64bit fine, streaming by the VLC program is also fine in both 32/64bit.

Thanks,
Hao

Reply·Email·View Thread·Permalink·Bookmark

Re: 64bit Streaming intermittent, 32bit works fine

Jason Newland

14-Nov-13 17:10 

The 64bit version of the VLC library is (even as admitted by the VideoLAN team) to be "buggy". So this would be a problem with the 64bit version of VLC not nVLC library. The VLC program itself probably has some funky "hack" going on behind the scenes to make stuff work properly (or at least appear to) until the library coders can work out all the bugs.64位vlc有很多bug。

延迟

Hi, roman.
Server display have some delay appx. 0.3 second, but client player have 2.3 delayed play.(UDP, RTP)
Here is my code sample.

Server Code
string output = @":sout=#transcode{vcodec=mp4v,vb=4096,fps=30,width=1280,height=720,acodec=none}:duplicate{";
output += "dst=display,";
output += "dst=rtp{mux=ts,dst=192.168.1.100,port=7000}}";
m_media = m_factory.CreateMedia(MediaStrings.DSHOW, output);
m_media.AddOptionFlag("--udp-caching=0",1);
m_media.AddOptionFlag("--rtp-caching=0",1);
m_media.AddOptionFlag("--rtsp-caching=0",1);
m_player.Open(m_media);
m_player.Play();

Client Code
m_media = m_factory.CreateMedia("rtp://@:7000");
m_media.AddOptionFlag("--udp-caching=0", 1);
m_media.AddOptionFlag("--rtp-caching=0", 1);
m_media.AddOptionFlag("--rtsp-caching=0", 1);
m_player.Open(m_media);
m_player.Play();

Please help me.
Thank in advance.

Hi, shin mun yong
You should setup the X264 encoder parameter if you used the default x264 encoder

不要在TCP上用RTSP

Can we stream out video from RTSP TCP ?

reymond

1-May-12 19:00 

Hi Roman, 

Can we configure the Streaming Out using TCP RTSP rather than used UDP RTP ? 

Thanks.

Reply·Email·View Thread·Permalink·Bookmark

Re: Can we stream out video from RTSP TCP ?/p>

roman_gin/p>

4-May-12 5:21 

Hi, 

Never tried this. Check this link for more details 

http://www.videolan.org/streaming-features.html[^]

PlayerBuffering

结果是个float,用不上

生成Buffer流程:
es_out.c->EsOutDecodersStopBuffering>>event.c->input_SendEventCache
增加接口的流程:
media_player.c->input_event_changed>>
1、增加newval.i_int == INPUT_EVENT_CACHE的处理判断;
通知libvlc_MediaPlayerBuffering事件处理。
2、增加libvlc_MediaPlayerBuffering事件的处理,
修改libvlc_events.h中的libvlc_event_t结构,增加
/* buffering处理*/
struct
{
float new_cache;
} media_player_buffering_changed;
结构;
3、在newval.i_int == INPUT_EVENT_CACHE处理中加入如下代码
/* */
event.type = libvlc_MediaPlayerBuffering;
event.u.media_player_buffering_changed.new_cache =
var_GetFloat( p_input, "cache" );
libvlc_event_send( p_mi->p_event_manager, &event );
全部重新编译,OK。
这样就可以在事件处理中直接得到Buffering信息了。
libvlc_event_attach(eventManager, libvlc_MediaPlayerBuffering,
handle_Buffering_changed_event, this);
libvlc_event_detach(eventManager, libvlc_MediaPlayerBuffering,
handle_Buffering_changed_event, this);

组播接收也有可能

先试试通不通吧,vlc没报找不到
Transcode the input stream and send it to a multicast IP address with the associated SAP announce:

% vlc -vvv input_stream --sout '#transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128,deinterlace}:
rtp{mux=ts,dst=239.255.12.42,port=5004,sdp=sap://,name="TestStream"}' 

Display the input stream, transcode it and send it to a multicast IP address with the associated SAP announce:

% vlc -vvv input_stream --sout '#duplicate{dst=display,dst=
"transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128,deinterlace}:
rtp{mux=ts,dst=239.255.12.42,port=5004,sdp=sap://,name="TestStream"}"}' 

Transcode the input stream, display the transcoded stream and send it to a multicast IP address with the associated SAP announce:

% vlc -vvv input_stream --sout '#transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128,deinterlace}:
duplicate{dst=display,dst=rtp{mux=ts,dst=239.255.12.42,port=5004,sdp=sap://,name="TestStream"}}' 

录制功能

前提是要修改代码

在这篇文章vlc android的编译及截图,录制视频等功能里,我找到了用vlc实现Android版本截图的功能,但是录制视频的功能是不正确的。
其录制视频的方法,对vlc底层的开始录制和结束录制,都不能很好的控制。
鉴于此,我们对vlc代码进行修改,编译。
参见http://patches.videolan.org/patch/606/

diff --git a/include/vlc/libvlc_events.h b/include/vlc/libvlc_events.h
index 2cfedbf..25a16ea 100644
--- a/include/vlc/libvlc_events.h
+++ b/include/vlc/libvlc_events.h
@@ -72,6 +72,8 @@  enum libvlc_event_e {
libvlc_MediaPlayerSnapshotTaken,
libvlc_MediaPlayerLengthChanged,
libvlc_MediaPlayerVout,
+    libvlc_MediaPlayerRecordableChanged,
+    libvlc_MediaPlayerRecordingFinished,

libvlc_MediaListItemAdded=0x200,
libvlc_MediaListWillAddItem,
@@ -165,6 +167,14 @@  typedef struct libvlc_event_t
} media_player_pausable_changed;
struct
{
+            int new_recordable;
+        } media_player_recordable_changed;
+        struct
+        {
+            char *psz_filename;
+        } media_player_recording_finished;
+        struct
+        {
int new_count;
} media_player_vout;

diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index aefef02..8ddef37 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -1628,6 +1628,121 @@  LIBVLC_API int libvlc_audio_set_delay( libvlc_media_player_t *p_mi, int64_t i_de

/** @} audio */

+/**
+ * Can the media player record the current media?
+ *
+ * Media must be buffering or playing before it can be recorded.
+ *
+ * The media player event manager will emit a libvlc_MediaPlayerRecordableChanged event
+ * when the recordable state changes after starting media playback. The event data will
+ * describe the new recordable state, so invocation of this API method is not strictly
+ * necessary to determine when recording can be started.
+ *
+ * A libvlc_MediaPlayerRecordableChanged event will not be emitted if the media is
+ * stopped (notified by a libvlc_MediaPlayerStoppedEvent) or finishes normally (notified
+ * by a libvlc_MediaPlayerFinished event).
+ *
+ * A calling application should therefore register an event callback for those events
+ * so that it may query the new recordable state and manage recording at the appropriate
+ * time.
+ *
+ * \param p_mi media player
+ * \return true if the media player can record, false if it can not
+ * \version LibVLC 2.1.0 or later
+ */
+LIBVLC_API bool libvlc_media_player_is_recordable( libvlc_media_player_t *p_mi );
+
+/**
+ * Is the current media being recorded?
+ *
+ * \param p_mi media player
+ * \return true if recording, false if not
+ * \version LibVLC 2.1.0 or later
+ */
+LIBVLC_API bool libvlc_media_player_is_recording( libvlc_media_player_t *p_mi );
+
+/**
+ * Start recording the current media.
+ *
+ * Media must be buffering or playing before it can be recorded. A calling application
+ * can begin recording immediately on receipt of a libvlc_MediaPlayerRecordableChanged
+ * event sent via the media player event manager (if recording is possible for the
+ * currently playing media), and any time thereafter until the media stops.
+ *
+ * Media will be saved to the file path denoted by the psz_filename parameter if it is
+ * supplied. Any such supplied filename should not include a file extension as the
+ * correct file extension will automatically be appended when the file is created. This
+ * filename may denote a full path name, but each directory in the path must already
+ * exist or recording will silently fail. If the calling application chooses to specify
+ * the filename then it is the responsibility of that application to take account of
+ * this and itself make sure any needed directories are created.
+ *
+ * Alternatively, a calling application need not supply a filename and so instead let
+ * vlc automatically generate a unique filename. This will cause vlc to create a new
+ * file in the appropriate media directory for the user - for example "~/Videos". The
+ * actual filename used will be sent in an event when the recording is complete.
+ *
+ * When recording has finished and the new file has been completely saved, a
+ * libvlc_MediaPlayerRecordingFinished event will be sent via the media player event
+ * manager. The event data will contain the filename of the newly recorded file - this
+ * will either be the filename as specified by the calling application or a filename
+ * generated by vlc if the application did not supply a filename. In either case, this
+ * filename will include the automatically appended file extension.
+ *
+ * The saved media file will not be immediately available or visible until recording
+ * has completely finished and the libvlc_MediaPlayerRecordingFinished event has been
+ * received, or the media has stopped or finished normally.
+ *
+ * Recording can be stopped and started on-the-fly once the recordable state is set;
+ * each time recording is stopped and restarted a new file will be created so a calling
+ * application should take care to provide unique filenames, or defer to vlc to create
+ * unique filenames.
+ *
+ * Recording will be stopped when the media stops playing, and must be explicitly
+ * started again to restart recording, i.e. the recording state is not automatically
+ * preserved when playing media subsequently.
+ *
+ * Media player functionailty such as next/previous chapter, set time or position and
+ * so on are ineffective when recording is enabled. However, pausing the media is
+ * possible and will pause the recording; unpausing the media will resume playback and
+ * recording.
+ *
+ * Recording of the primary media or sub-items is possible.
+ *
+ * \param p_mi media player
+ * \param psz_filename name of the file to save the media to, not including any file extension,
+ *                     or NULL if vlc should generate the filename automatically
+ * \return 0 if recording was started, -1 on error
+ * \version LibVLC 2.1.0 or later
+ */
+LIBVLC_API int libvlc_media_player_record_start( libvlc_media_player_t *p_mi, const char *psz_filename );
+
+/**
+ * Stop recording the current media.
+ *
+ * This method requests that the recording stop, and will return immediately. Recording
+ * will not stop immediately.
+ *
+ * When the recording actually stops some short time later and the new file has
+ * finished being written, a libvlc_MediaPlayerRecordingFinished event will be sent via
+ * the media player event manager. The newly recorded file will not be visible or
+ * available until after this event has been sent.
+ *
+ * The event data will contain the full name of the file that was created. The filename
+ * will either be that as was specified by the calling application on invoking
+ * libvlc_media_player_record_start(), or the filename that vlc automatically generated
+ * if the calling application did not supply its own filename. In either case the
+ * filename will contain the automatically appended file extension.
+ *
+ * There is no need to invoke this method to stop the recording if the media is stopped
+ * or finishes playing normally.
+ *
+ * \param p_mi media player
+ * \return 0 if recording was stopped, -1 on error
+ * \version LibVLC 2.1.0 or later
+ */
+LIBVLC_API int libvlc_media_player_record_stop( libvlc_media_player_t *p_mi );
+
/** @} media_player */

# ifdef __cplusplus
diff --git a/lib/event.c b/lib/event.c
index c71a48a..7ef4abd 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -279,6 +279,8 @@  static const event_name_t event_list[] = {
DEF(MediaPlayerSnapshotTaken)
DEF(MediaPlayerLengthChanged)
DEF(MediaPlayerVout)
+    DEF(MediaPlayerRecordableChanged)
+    DEF(MediaPlayerRecordingFinished)

DEF(MediaListItemAdded)
DEF(MediaListWillAddItem)
diff --git a/lib/libvlc.sym b/lib/libvlc.sym
index 42dad5c..3ff67ef 100644
--- a/lib/libvlc.sym
+++ b/lib/libvlc.sym
@@ -137,6 +137,8 @@  libvlc_media_player_get_title
libvlc_media_player_get_title_count
libvlc_media_player_get_xwindow
libvlc_media_player_has_vout
+libvlc_media_player_is_recordable
+libvlc_media_player_is_recording
libvlc_media_player_is_seekable
libvlc_media_player_is_playing
libvlc_media_player_new
@@ -146,6 +148,8 @@  libvlc_media_player_set_pause
libvlc_media_player_pause
libvlc_media_player_play
libvlc_media_player_previous_chapter
+libvlc_media_player_record_start
+libvlc_media_player_record_stop
libvlc_media_player_release
libvlc_media_player_retain
libvlc_media_player_set_agl
diff --git a/lib/media_player.c b/lib/media_player.c
index a41b8c7..6573197 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -64,6 +64,10 @@  input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
vlc_value_t oldval, vlc_value_t newval,
void * p_userdata );
static int
+input_recordable_changed( vlc_object_t *p_this, char const *psz_cmd,
+                          vlc_value_t oldval, vlc_value_t newval,
+                          void *p_userdata );
+static int
input_event_changed( vlc_object_t * p_this, char const * psz_cmd,
vlc_value_t oldval, vlc_value_t newval,
void * p_userdata );
@@ -72,6 +76,10 @@  static int
snapshot_was_taken( vlc_object_t *p_this, char const *psz_cmd,
vlc_value_t oldval, vlc_value_t newval, void *p_data );

+static int
+file_recording_finished( vlc_object_t *p_this, char const *psz_cmd,
+                         vlc_value_t oldval, vlc_value_t newval, void *p_data );
+
static void libvlc_media_player_destroy( libvlc_media_player_t *p_mi );

/*
@@ -132,6 +140,8 @@  static void release_input_thread( libvlc_media_player_t *p_mi, bool b_input_abor
input_seekable_changed, p_mi );
var_DelCallback( p_input_thread, "can-pause",
input_pausable_changed, p_mi );
+    var_DelCallback( p_input_thread, "can-record",
+                     input_recordable_changed, p_mi );
var_DelCallback( p_input_thread, "intf-event",
input_event_changed, p_mi );

@@ -227,6 +237,25 @@  input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
}

static int
+input_recordable_changed( vlc_object_t *p_this, char const *psz_cmd,
+                          vlc_value_t oldval, vlc_value_t newval,
+                          void *p_userdata )
+{
+    VLC_UNUSED(p_this);
+    VLC_UNUSED(psz_cmd);
+    VLC_UNUSED(oldval);
+
+    libvlc_media_player_t *p_mi = p_userdata;
+    libvlc_event_t event;
+
+    event.type = libvlc_MediaPlayerRecordableChanged;
+    event.u.media_player_recordable_changed.new_recordable = newval.b_bool;
+
+    libvlc_event_send( p_mi->p_event_manager, &event );
+    return VLC_SUCCESS;
+}
+
+static int
input_event_changed( vlc_object_t * p_this, char const * psz_cmd,
vlc_value_t oldval, vlc_value_t newval,
void * p_userdata )
@@ -357,6 +386,23 @@  static int snapshot_was_taken(vlc_object_t *p_this, char const *psz_cmd,
return VLC_SUCCESS;
}

+static int file_recording_finished(vlc_object_t *p_this, char const *psz_cmd,
+                                   vlc_value_t oldval, vlc_value_t newval, void *p_data )
+{
+    VLC_UNUSED(p_this);
+    VLC_UNUSED(psz_cmd);
+    VLC_UNUSED(oldval);
+
+    libvlc_media_player_t *p_mi = p_data;
+    libvlc_event_t event;
+
+    event.type = libvlc_MediaPlayerRecordingFinished;
+    event.u.media_player_recording_finished.psz_filename = newval.psz_string;
+
+    libvlc_event_send(p_mi->p_event_manager, &event);
+    return VLC_SUCCESS;
+}
+
static input_thread_t *find_input (vlc_object_t *obj)
{
libvlc_media_player_t *mp = (libvlc_media_player_t *)obj;
@@ -480,6 +526,10 @@  libvlc_media_player_new( libvlc_instance_t *instance )
var_Create (mp, "amem-set-volume", VLC_VAR_ADDRESS);
var_Create (mp, "amem-format", VLC_VAR_STRING | VLC_VAR_DOINHERIT);
var_Create (mp, "amem-rate", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);
+
+    var_Create (mp, "recording-finished", VLC_VAR_STRING);
+    var_AddCallback (mp, "recording-finished", file_recording_finished, mp);
+
var_Create (mp, "amem-channels", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT);

mp->p_md = NULL;
@@ -515,6 +565,9 @@  libvlc_media_player_new( libvlc_instance_t *instance )
register_event(mp, TitleChanged);
register_event(mp, PausableChanged);

+    register_event(mp, RecordableChanged);
+    register_event(mp, RecordingFinished);
+
register_event(mp, Vout);

/* Snapshot initialization */
@@ -566,6 +619,8 @@  static void libvlc_media_player_destroy( libvlc_media_player_t *p_mi )
var_DelCallback( p_mi->p_libvlc,
"snapshot-file", snapshot_was_taken, p_mi );

+    var_DelCallback( p_mi, "recording-finished", file_recording_finished, p_mi );
+
/* No need for lock_input() because no other threads knows us anymore */
if( p_mi->input.p_thread )
release_input_thread(p_mi, true);
@@ -732,12 +787,14 @@  int libvlc_media_player_play( libvlc_media_player_t *p_mi )

var_AddCallback( p_input_thread, "can-seek", input_seekable_changed, p_mi );
var_AddCallback( p_input_thread, "can-pause", input_pausable_changed, p_mi );
+    var_AddCallback( p_input_thread, "can-record", input_recordable_changed, p_mi );
var_AddCallback( p_input_thread, "intf-event", input_event_changed, p_mi );

if( input_Start( p_input_thread ) )
{
unlock_input(p_mi);
var_DelCallback( p_input_thread, "intf-event", input_event_changed, p_mi );
+        var_DelCallback( p_input_thread, "can-record", input_recordable_changed, p_mi );
var_DelCallback( p_input_thread, "can-pause", input_pausable_changed, p_mi );
var_DelCallback( p_input_thread, "can-seek", input_seekable_changed, p_mi );
vlc_object_release( p_input_thread );
@@ -1409,3 +1466,62 @@  void libvlc_media_player_next_frame( libvlc_media_player_t *p_mi )
vlc_object_release( p_input_thread );
}
}
+
+bool libvlc_media_player_is_recordable( libvlc_media_player_t *p_mi )
+{
+    input_thread_t *p_input_thread;
+    bool b_can_record;
+
+    p_input_thread = libvlc_get_input_thread( p_mi );
+    if( !p_input_thread )
+        return false;
+
+    b_can_record = var_GetBool( p_input_thread, "can-record" );
+
+    vlc_object_release( p_input_thread );
+    return b_can_record;
+}
+
+bool libvlc_media_player_is_recording( libvlc_media_player_t *p_mi )
+{
+    input_thread_t *p_input_thread;
+    bool b_record;
+
+    p_input_thread = libvlc_get_input_thread( p_mi );
+    if( !p_input_thread )
+        return false;
+
+    b_record = var_GetBool( p_input_thread, "record" );
+
+    vlc_object_release( p_input_thread );
+    return b_record;
+}
+
+int libvlc_media_player_record_start( libvlc_media_player_t *p_mi, const char* psz_filename )
+{
+    input_thread_t *p_input_thread;
+
+    p_input_thread = libvlc_get_input_thread( p_mi );
+    if( !p_input_thread )
+        return -1;
+
+    var_SetString( p_input_thread, "input-record-path", psz_filename );
+    var_SetBool( p_input_thread, "record", true );
+
+    vlc_object_release( p_input_thread );
+    return 0;
+}
+
+int libvlc_media_player_record_stop( libvlc_media_player_t *p_mi )
+{
+    input_thread_t *p_input_thread;
+
+    p_input_thread = libvlc_get_input_thread( p_mi );
+    if( !p_input_thread )
+        return -1;
+
+    var_SetBool( p_input_thread, "record", false );
+
+    vlc_object_release( p_input_thread );
+    return 0;
+}
diff --git a/modules/stream_out/record.c b/modules/stream_out/record.c
index de6d32e..40ddfea 100644
--- a/modules/stream_out/record.c
+++ b/modules/stream_out/record.c
@@ -110,6 +110,8 @@  struct sout_stream_sys_t
int              i_id;
sout_stream_id_t **id;
mtime_t     i_dts_start;
+
+    char *psz_record_file;
};

static void OutputStart( sout_stream_t *p_stream );
@@ -158,6 +160,8 @@  static int Open( vlc_object_t *p_this )
p_sys->i_dts_start = 0;
TAB_INIT( p_sys->i_id, p_sys->id );

+    p_sys->psz_record_file = NULL;
+
return VLC_SUCCESS;
}

@@ -172,6 +176,19 @@  static void Close( vlc_object_t * p_this )
if( p_sys->p_out )
sout_StreamChainDelete( p_sys->p_out, p_sys->p_out );

+    if( p_sys->psz_record_file ) {
+        for( vlc_object_t *p_mp = p_stream->p_parent; p_mp; p_mp = p_mp->p_parent )
+        {
+            if( var_Type( p_mp, "recording-finished" ) )
+            {
+                var_SetString( p_mp, "recording-finished", p_sys->psz_record_file );
+                break;
+            }
+        }
+
+        free( p_sys->psz_record_file );
+    }
+
TAB_CLEAN( p_sys->i_id, p_sys->id );
free( p_sys->psz_prefix );
free( p_sys );
@@ -352,7 +369,10 @@  static int OutputNew( sout_stream_t *p_stream,
}

if( psz_file && psz_extension )
+    {
+        p_sys->psz_record_file = strdup( psz_file );
var_SetString( p_stream->p_libvlc, "record-file", psz_file );
+    }

free( psz_file );
free( psz_output );
diff --git a/src/input/var.c b/src/input/var.c
index 9613fe2..04f33b9 100644
--- a/src/input/var.c
+++ b/src/input/var.c
@@ -210,6 +210,9 @@  void input_ControlVarInit ( input_thread_t *p_input )
text.psz_string = _("Subtitles Track");
var_Change( p_input, "spu-es", VLC_VAR_SETTEXT, &text, NULL );

+    /* ES Out */
+    var_Create( p_input, "input-record-path", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
+
/* Special read only objects variables for intf */
var_Create( p_input, "bookmarks", VLC_VAR_STRING | VLC_VAR_DOINHERIT );

再此基础上,添加jni的接口,编译,然后给java应用层调用,就可以实现Android版的vlc录制视频了。

 

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内