[Android] LibVLC: MediaPlayer: add record() method

Thomas Guillem git at videolan.org
Tue Apr 2 17:00:00 CEST 2019


vlc-android | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Mar 28 11:50:55 2019 +0100| [17d0f8d697147ec72dd61ac0d9758dd4e982f0ca] | committer: Geoffrey Métais

LibVLC: MediaPlayer: add record() method

> https://code.videolan.org/videolan/vlc-android/commit/17d0f8d697147ec72dd61ac0d9758dd4e982f0ca
---

 libvlc/jni/libvlcjni-mediaplayer.c                 | 36 +++++++++++
 ...03-libvlc-events-Add-callbacks-for-record.patch | 74 ++++++++++++++++++++++
 ...tput-file-Add-error-dialog-for-write-open.patch | 40 ++++++++++++
 ...005-libvlc-media_player-Add-record-method.patch | 69 ++++++++++++++++++++
 libvlc/src/org/videolan/libvlc/MediaPlayer.java    | 12 ++++
 5 files changed, 231 insertions(+)

diff --git a/libvlc/jni/libvlcjni-mediaplayer.c b/libvlc/jni/libvlcjni-mediaplayer.c
index 59a48a080..4f7438c76 100644
--- a/libvlc/jni/libvlcjni-mediaplayer.c
+++ b/libvlc/jni/libvlcjni-mediaplayer.c
@@ -22,6 +22,7 @@
 
 #include <pthread.h>
 #include <stdlib.h>
+#include <dlfcn.h>
 
 #include "libvlcjni-vlcobject.h"
 
@@ -1072,6 +1073,41 @@ Java_org_videolan_libvlc_MediaPlayer_nativeSetEqualizer(JNIEnv *env,
     return libvlc_media_player_set_equalizer(p_obj->u.p_mp, p_eq) == 0 ? true: false;
 }
 
+jboolean
+Java_org_videolan_libvlc_MediaPlayer_nativeRecord(JNIEnv *env, jobject thiz,
+                                                  jstring jdirectory)
+{
+    vlcjni_object *p_obj = VLCJniObject_getInstance(env, thiz);
+    const char *psz_directory;
+
+    if (!p_obj)
+        return false;
+
+    int (*record_func)(libvlc_media_player_t *, const char *) =
+        dlsym(RTLD_DEFAULT, "libvlc_media_player_record");
+
+    if (!record_func)
+        return false;
+
+    if (jdirectory)
+    {
+        psz_directory = (*env)->GetStringUTFChars(env, jdirectory, 0);
+        if (!psz_directory)
+        {
+            throw_Exception(env, VLCJNI_EX_ILLEGAL_ARGUMENT, "directory invalid");
+            return false;
+        }
+    }
+    else
+        psz_directory = NULL;
+
+    jboolean ret = record_func(p_obj->u.p_mp, psz_directory) == 0;
+
+    (*env)->ReleaseStringUTFChars(env, jdirectory, psz_directory);
+
+    return ret;
+}
+
 jint
 Java_org_videolan_libvlc_MediaPlayer_00024Equalizer_nativeGetPresetCount(JNIEnv *env,
                                                                          jobject thiz)
diff --git a/libvlc/patches/0003-libvlc-events-Add-callbacks-for-record.patch b/libvlc/patches/0003-libvlc-events-Add-callbacks-for-record.patch
new file mode 100644
index 000000000..c7eeb0a71
--- /dev/null
+++ b/libvlc/patches/0003-libvlc-events-Add-callbacks-for-record.patch
@@ -0,0 +1,74 @@
+From c4b67a2d0823729d0057155f828a7624d36059c9 Mon Sep 17 00:00:00 2001
+From: Soomin Lee <bubu at mikan.io>
+Date: Thu, 27 Sep 2018 18:40:39 +0200
+Subject: [PATCH 3/4] libvlc: events: Add callbacks for record
+
+---
+ include/vlc/libvlc_events.h |  9 +++++++++
+ lib/media_player.c          | 16 ++++++++++++++++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/include/vlc/libvlc_events.h b/include/vlc/libvlc_events.h
+index f8b0e9b5b2..bbc6bc0eec 100644
+--- a/include/vlc/libvlc_events.h
++++ b/include/vlc/libvlc_events.h
+@@ -32,6 +32,8 @@
+ 
+ # ifdef __cplusplus
+ extern "C" {
++# else
++#  include <stdbool.h>
+ # endif
+ 
+ typedef struct libvlc_renderer_item_t libvlc_renderer_item_t;
+@@ -86,6 +88,7 @@ enum libvlc_event_e {
+     libvlc_MediaPlayerAudioVolume,
+     libvlc_MediaPlayerAudioDevice,
+     libvlc_MediaPlayerChapterChanged,
++    libvlc_MediaPlayerRecordChanged,
+ 
+     libvlc_MediaListItemAdded=0x200,
+     libvlc_MediaListWillAddItem,
+@@ -275,6 +278,12 @@ typedef struct libvlc_event_t
+             const char *device;
+         } media_player_audio_device;
+ 
++        struct
++        {
++            const char *file_path;
++            bool recording;
++        } media_player_record_changed;
++
+         struct
+         {
+             libvlc_renderer_item_t *item;
+diff --git a/lib/media_player.c b/lib/media_player.c
+index 354272b32d..e337cf7197 100644
+--- a/lib/media_player.c
++++ b/lib/media_player.c
+@@ -446,6 +446,22 @@ input_event_changed( vlc_object_t * p_this, char const * psz_cmd,
+             }
+         }
+     }
++    else if ( newval.i_int == INPUT_EVENT_RECORD )
++    {
++        bool recording = var_GetBool( p_input, "record" );
++        char *file_path = NULL;
++
++        if ( !recording )
++            file_path = var_GetString( p_mi->obj.libvlc, "record-file" );
++
++        event.type = libvlc_MediaPlayerRecordChanged;
++        event.u.media_player_record_changed.file_path = file_path;
++        event.u.media_player_record_changed.recording = recording;
++
++        libvlc_event_send( &p_mi->event_manager, &event );
++
++        free( file_path );
++    }
+ 
+     return VLC_SUCCESS;
+ }
+-- 
+2.20.1
+
diff --git a/libvlc/patches/0004-access_output-file-Add-error-dialog-for-write-open.patch b/libvlc/patches/0004-access_output-file-Add-error-dialog-for-write-open.patch
new file mode 100644
index 000000000..8d5c5b921
--- /dev/null
+++ b/libvlc/patches/0004-access_output-file-Add-error-dialog-for-write-open.patch
@@ -0,0 +1,40 @@
+From 88ddce79a49dc6b88033844d36666848ce1a8365 Mon Sep 17 00:00:00 2001
+From: Soomin Lee <bubu at mikan.io>
+Date: Mon, 1 Oct 2018 15:37:57 +0200
+Subject: [PATCH 4/4] access_output: file: Add error dialog for write/open
+
+---
+ modules/access_output/file.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/modules/access_output/file.c b/modules/access_output/file.c
+index fbefce0be8..45de0fc75e 100644
+--- a/modules/access_output/file.c
++++ b/modules/access_output/file.c
+@@ -88,6 +88,9 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
+         {
+             if (errno == EINTR)
+                 continue;
++            if (errno == ENOSPC)
++                vlc_dialog_display_error(p_access, "record",
++                                         "An error occurred during recording. Error: %s", vlc_strerror_c(errno));
+             block_ChainRelease (p_buffer);
+             msg_Err( p_access, "cannot write: %s", vlc_strerror_c(errno) );
+             return -1;
+@@ -305,8 +308,13 @@ static int Open( vlc_object_t *p_this )
+             if (fd != -1)
+                 break;
+             if (fd == -1)
++            {
+                 msg_Err (p_access, "cannot create %s: %s", path,
+                          vlc_strerror_c(errno));
++
++                vlc_dialog_display_error(p_access, "record",
++                                         "An error occurred during recording. Error: %s", vlc_strerror_c(errno));
++            }
+             if (overwrite || errno != EEXIST)
+                 break;
+             flags &= ~O_EXCL;
+-- 
+2.20.1
+
diff --git a/libvlc/patches/0005-libvlc-media_player-Add-record-method.patch b/libvlc/patches/0005-libvlc-media_player-Add-record-method.patch
new file mode 100644
index 000000000..74a85f8b6
--- /dev/null
+++ b/libvlc/patches/0005-libvlc-media_player-Add-record-method.patch
@@ -0,0 +1,69 @@
+From a16ca81ddc53c2275f6946ceb979f28b50bfb069 Mon Sep 17 00:00:00 2001
+From: Soomin Lee <bubu at mikan.io>
+Date: Wed, 31 Oct 2018 10:08:55 +0100
+Subject: [PATCH 2/4] libvlc: media_player: Add record method
+
+---
+ include/vlc/libvlc_media_player.h | 11 +++++++++++
+ lib/media_player.c                | 19 +++++++++++++++++++
+ 2 files changed, 30 insertions(+)
+
+diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
+index c431c235e9..8629fbc1a1 100644
+--- a/include/vlc/libvlc_media_player.h
++++ b/include/vlc/libvlc_media_player.h
+@@ -2079,6 +2079,17 @@ LIBVLC_API int libvlc_media_player_get_role(libvlc_media_player_t *p_mi);
+  */
+ LIBVLC_API int libvlc_media_player_set_role(libvlc_media_player_t *p_mi,
+                                             unsigned role);
++/**
++ * Start/stop recording
++ *
++ * \version LibVLC 4.0.0 and later.
++ *
++ * \param p_mi media player
++ * \param directory path of the recording directory or NULL to stop recording
++ * \return 0 on success, -1 on error
++ */
++LIBVLC_API int libvlc_media_player_record(libvlc_media_player_t *p_mi,
++                                          const char *directory);
+ 
+ /** @} audio */
+ 
+diff --git a/lib/media_player.c b/lib/media_player.c
+index a9a22fee15..354272b32d 100644
+--- a/lib/media_player.c
++++ b/lib/media_player.c
+@@ -621,6 +621,7 @@ libvlc_media_player_new( libvlc_instance_t *instance )
+     var_Create (mp, "rate", VLC_VAR_FLOAT|VLC_VAR_DOINHERIT);
+     var_Create (mp, "sout", VLC_VAR_STRING);
+     var_Create (mp, "demux-filter", VLC_VAR_STRING);
++    var_Create (mp, "input-record-path", VLC_VAR_STRING);
+ 
+     /* Video */
+     var_Create (mp, "vout", VLC_VAR_STRING|VLC_VAR_DOINHERIT);
+@@ -2078,3 +2079,21 @@ int libvlc_media_player_get_role(libvlc_media_player_t *mp)
+     free(str);
+     return ret;
+ }
++
++int libvlc_media_player_record( libvlc_media_player_t *p_mi,
++                                const char *directory )
++{
++    vlc_value_t val = { .psz_string = (char *)directory };
++    const bool enable = directory != NULL;
++    input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi );
++    if( !p_input_thread )
++        return VLC_EGENERIC;
++
++    if( enable )
++        var_Set( p_mi, "input-record-path", val );
++
++    var_SetBool( p_input_thread, "record", enable);
++
++    vlc_object_release( p_input_thread );
++    return VLC_SUCCESS;
++}
+-- 
+2.20.1
+
diff --git a/libvlc/src/org/videolan/libvlc/MediaPlayer.java b/libvlc/src/org/videolan/libvlc/MediaPlayer.java
index 8827a8f11..57f28134e 100644
--- a/libvlc/src/org/videolan/libvlc/MediaPlayer.java
+++ b/libvlc/src/org/videolan/libvlc/MediaPlayer.java
@@ -1195,6 +1195,17 @@ public class MediaPlayer extends VLCObject<MediaPlayer.Event> {
         return nativeAddSlave(type, VLCUtil.encodeVLCUri(uri), select);
     }
 
+    /**
+     * Start/stop recording
+     *
+     * @param directory path of the recording directory or null to stop
+     * recording
+     * @return true on success.
+     */
+    public boolean record(String directory) {
+        return nativeRecord(directory);
+    }
+
     /**
      * Add a slave (or subtitle) to the current media player.
      *
@@ -1381,5 +1392,6 @@ public class MediaPlayer extends VLCObject<MediaPlayer.Event> {
     private native long nativeGetSpuDelay();
     private native boolean nativeSetSpuDelay(long delay);
     private native boolean nativeAddSlave(int type, String location, boolean select);
+    private native boolean nativeRecord(String directory);
     private native boolean nativeSetEqualizer(Equalizer equalizer);
 }



More information about the Android mailing list