moz-plugin: Improve subtitle and audio track JS bindings
authorCyril Mathé <cmathe@actech-innovation.com>
Fri, 15 May 2009 12:49:34 +0000 (14:49 +0200)
committerJean-Baptiste Kempf <jb@videolan.org>
Tue, 26 May 2009 12:29:28 +0000 (14:29 +0200)
- audio.count: give the number of available audio track
  - audio.description(int n): give the name of the n-th audio track
  - subtitle.count: give the number of available subtitle track
  - subtitle.description(int n): give the name of the n-th subtitle track
  - subtitle.track: get and set the subtitle track to show (similar as video.subtitle)

Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
projects/mozilla/control/npolibvlc.cpp
projects/mozilla/control/npolibvlc.h

index 850fcbe..5f49b24 100644 (file)
@@ -75,6 +75,7 @@ const NPUTF8 * const LibvlcRootNPObject::propertyNames[] =
     "audio",
     "input",
     "playlist",
+    "subtitle",
     "video",
     "VersionInfo",
 };
@@ -85,6 +86,7 @@ enum LibvlcRootNPObjectPropertyIds
     ID_root_audio = 0,
     ID_root_input,
     ID_root_playlist,
+    ID_root_subtitle,
     ID_root_video,
     ID_root_VersionInfo,
 };
@@ -121,6 +123,14 @@ LibvlcRootNPObject::getProperty(int index, NPVariant &result)
                           RuntimeNPClass<LibvlcPlaylistNPObject>::getClass());
                 OBJECT_TO_NPVARIANT(NPN_RetainObject(playlistObj), result);
                 return INVOKERESULT_NO_ERROR;
+            case ID_root_subtitle:
+                // create child object in lazyman fashion to avoid
+                // ownership problem with firefox
+                if( ! subtitleObj )
+                    subtitleObj = NPN_CreateObject(_instance,
+                             RuntimeNPClass<LibvlcSubtitleNPObject>::getClass());
+                OBJECT_TO_NPVARIANT(NPN_RetainObject(subtitleObj), result);
+                return INVOKERESULT_NO_ERROR;
             case ID_root_video:
                 // create child object in lazyman fashion to avoid
                 // ownership problem with firefox
@@ -180,6 +190,7 @@ const NPUTF8 * const LibvlcAudioNPObject::propertyNames[] =
     "mute",
     "volume",
     "track",
+    "count",
     "channel",
 };
 COUNTNAMES(LibvlcAudioNPObject,propertyCount,propertyNames);
@@ -189,6 +200,7 @@ enum LibvlcAudioNPObjectPropertyIds
     ID_audio_mute,
     ID_audio_volume,
     ID_audio_track,
+    ID_audio_count,
     ID_audio_channel,
 };
 
@@ -227,6 +239,17 @@ LibvlcAudioNPObject::getProperty(int index, NPVariant &result)
                 INT32_TO_NPVARIANT(track, result);
                 return INVOKERESULT_NO_ERROR;
             }
+            case ID_audio_count:
+            {
+                libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
+                RETURN_ON_EXCEPTION(this,ex);
+                // get the number of audio track available
+                int i_track = libvlc_audio_get_track_count(p_md, &ex);
+                RETURN_ON_EXCEPTION(this,ex);
+                // return it
+                INT32_TO_NPVARIANT(i_track, result);
+                return INVOKERESULT_NO_ERROR;
+            }
             case ID_audio_channel:
             {
                 int channel = libvlc_audio_get_channel(p_plugin->getVLC(), &ex);
@@ -300,12 +323,14 @@ LibvlcAudioNPObject::setProperty(int index, const NPVariant &value)
 const NPUTF8 * const LibvlcAudioNPObject::methodNames[] =
 {
     "toggleMute",
+    "description",
 };
 COUNTNAMES(LibvlcAudioNPObject,methodCount,methodNames);
 
 enum LibvlcAudioNPObjectMethodIds
 {
     ID_audio_togglemute,
+    ID_audio_description,
 };
 
 RuntimeNPObject::InvokeResult
@@ -330,6 +355,50 @@ LibvlcAudioNPObject::invoke(int index, const NPVariant *args,
                     return INVOKERESULT_NO_ERROR;
                 }
                 return INVOKERESULT_NO_SUCH_METHOD;
+            case ID_audio_description:
+            {
+                if( argCount == 1)
+                {
+                    char *psz_name;
+                    int i_trackID, i_limit, i;
+                    libvlc_track_description_t *p_trackDesc;
+
+                    libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
+                    RETURN_ON_EXCEPTION(this,ex);
+
+                    /* get tracks description */
+                    p_trackDesc = libvlc_audio_get_track_description(p_md, &ex);
+                    RETURN_ON_EXCEPTION(this,ex);
+                    if( !p_trackDesc )
+                        return INVOKERESULT_GENERIC_ERROR;
+
+                    /* get the number of track available */
+                    i_limit = libvlc_audio_get_track_count(p_md, &ex);
+                    RETURN_ON_EXCEPTION(this,ex);
+
+                    /* check if a number is given by the user
+                     * and get the track number */
+                    if( isNumberValue(args[0]) )
+                        i_trackID = numberValue(args[0]);
+                    else
+                        return INVOKERESULT_INVALID_VALUE;
+
+                    /* if bad number is given return invalid value */
+                    if ( ( i_trackID > ( i_limit - 1 ) ) || ( i_trackID < 0 ) )
+                        return INVOKERESULT_INVALID_VALUE;
+
+                    /* get the good trackDesc */
+                    for( i = 0 ; i < i_trackID ; i++ )
+                    {
+                        p_trackDesc = p_trackDesc->p_next;
+                    }
+                    psz_name = p_trackDesc->psz_name;
+
+                    /* display the name of the track chosen */
+                    return invokeResultString( psz_name, result );
+                }
+                return INVOKERESULT_NO_SUCH_METHOD;
+            }
             default:
                 ;
         }
@@ -1031,6 +1100,168 @@ void LibvlcPlaylistNPObject::parseOptions(NPObject *obj, int *i_options,
     }
 }
 
+/*
+** implementation of libvlc subtitle object
+*/
+
+const NPUTF8 * const LibvlcSubtitleNPObject::propertyNames[] =
+{
+    "track",
+    "count",
+};
+
+enum LibvlcSubtitleNPObjectPropertyIds
+{
+    ID_subtitle_track,
+    ID_subtitle_count,
+};
+COUNTNAMES(LibvlcSubtitleNPObject,propertyCount,propertyNames);
+
+RuntimeNPObject::InvokeResult
+LibvlcSubtitleNPObject::getProperty(int index, NPVariant &result)
+{
+    /* is plugin still running */
+    if( isPluginRunning() )
+    {
+        VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
+        libvlc_exception_t ex;
+        libvlc_exception_init(&ex);
+
+        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
+        RETURN_ON_EXCEPTION(this,ex);
+
+        switch( index )
+        {
+            case ID_subtitle_track:
+            {
+                /* get the current subtitle ID */
+                int i_spu = libvlc_video_get_spu(p_md, &ex);
+                RETURN_ON_EXCEPTION(this,ex);
+                /* return it */
+                INT32_TO_NPVARIANT(i_spu, result);
+                return INVOKERESULT_NO_ERROR;
+            }
+            case ID_subtitle_count:
+            {
+                /* get the number of subtitles available */
+                int i_spu = libvlc_video_get_spu_count(p_md, &ex);
+                RETURN_ON_EXCEPTION(this,ex);
+                /* return it */
+                INT32_TO_NPVARIANT(i_spu, result);
+                return INVOKERESULT_NO_ERROR;
+            }
+        }
+    }
+    return INVOKERESULT_GENERIC_ERROR;
+}
+
+RuntimeNPObject::InvokeResult
+LibvlcSubtitleNPObject::setProperty(int index, const NPVariant &value)
+{
+    /* is plugin still running */
+    if( isPluginRunning() )
+    {
+        VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
+        libvlc_exception_t ex;
+        libvlc_exception_init(&ex);
+
+        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
+        RETURN_ON_EXCEPTION(this,ex);
+
+        switch( index )
+        {
+            case ID_subtitle_track:
+            {
+                if( isNumberValue(value) )
+                {
+                    /* set the new subtitle track to show */
+                    libvlc_video_set_spu(p_md, numberValue(value), &ex);
+                    RETURN_ON_EXCEPTION(this,ex);
+
+                    return INVOKERESULT_NO_ERROR;
+                }
+                return INVOKERESULT_INVALID_VALUE;
+            }
+        }
+    }
+    return INVOKERESULT_GENERIC_ERROR;
+}
+
+const NPUTF8 * const LibvlcSubtitleNPObject::methodNames[] =
+{
+    "description"
+};
+COUNTNAMES(LibvlcSubtitleNPObject,methodCount,methodNames);
+
+enum LibvlcSubtitleNPObjectMethodIds
+{
+    ID_subtitle_description
+};
+
+RuntimeNPObject::InvokeResult
+LibvlcSubtitleNPObject::invoke(int index, const NPVariant *args,
+                            uint32_t argCount, NPVariant &result)
+{
+    /* is plugin still running */
+    if( isPluginRunning() )
+    {
+        VlcPlugin* p_plugin = getPrivate<VlcPlugin>();
+        libvlc_exception_t ex;
+        libvlc_exception_init(&ex);
+
+        libvlc_media_player_t *p_md = p_plugin->getMD(&ex);
+        RETURN_ON_EXCEPTION(this,ex);
+
+        switch( index )
+        {
+            case ID_subtitle_description:
+            {
+                if( argCount == 1)
+                {
+                    char *psz_name;
+                    int i_spuID, i_limit, i;
+                    libvlc_track_description_t *p_spuDesc;
+
+                    /* get subtitles description */
+                    p_spuDesc = libvlc_video_get_spu_description(p_md, &ex);
+                    RETURN_ON_EXCEPTION(this,ex);
+                    if( !p_spuDesc )
+                        return INVOKERESULT_GENERIC_ERROR;
+
+                    /* get the number of subtitle available */
+                    i_limit = libvlc_video_get_spu_count(p_md, &ex);
+                    RETURN_ON_EXCEPTION(this,ex);
+
+                    /* check if a number is given by the user
+                     * and get the subtitle number */
+                    if( isNumberValue(args[0]) )
+                        i_spuID = numberValue(args[0]);
+                    else
+                        return INVOKERESULT_INVALID_VALUE;
+
+                    /* if bad number is given return invalid value */
+                    if ( ( i_spuID > ( i_limit -1 ) ) || ( i_spuID < 0 ) )
+                        return INVOKERESULT_INVALID_VALUE;
+
+                    /* get the good spuDesc */
+                    for( i = 0 ; i < i_spuID ; i++ )
+                    {
+                        p_spuDesc = p_spuDesc->p_next;
+                    }
+                    psz_name = p_spuDesc->psz_name;
+
+                    /* return the name of the track chosen */
+                    return invokeResultString(psz_name, result);
+                }
+                return INVOKERESULT_NO_SUCH_METHOD;
+            }
+            default:
+                return INVOKERESULT_NO_SUCH_METHOD;
+        }
+    }
+    return INVOKERESULT_GENERIC_ERROR;
+}
+
 /*
 ** implementation of libvlc video object
 */
index 3a68b52..b447ef7 100644 (file)
@@ -37,6 +37,7 @@ protected:
     audioObj(NULL),
     inputObj(NULL),
     playlistObj(NULL),
+    subtitleObj(NULL),
     videoObj(NULL) {};
 
     virtual ~LibvlcRootNPObject();
@@ -55,6 +56,7 @@ private:
     NPObject *audioObj;
     NPObject *inputObj;
     NPObject *playlistObj;
+    NPObject *subtitleObj;
     NPObject *videoObj;
 };
 
@@ -147,6 +149,28 @@ private:
     NPObject*  playlistItemsObj;
 };
 
+class LibvlcSubtitleNPObject: public RuntimeNPObject
+{
+protected:
+    friend class RuntimeNPClass<LibvlcSubtitleNPObject>;
+
+    LibvlcSubtitleNPObject(NPP instance, const NPClass *aClass) :
+        RuntimeNPObject(instance, aClass) {};
+    virtual ~LibvlcSubtitleNPObject() {};
+
+    static const int propertyCount;
+    static const NPUTF8 * const propertyNames[];
+
+    InvokeResult getProperty(int index, NPVariant &result);
+    InvokeResult setProperty(int index, const NPVariant &value);
+
+    static const int methodCount;
+    static const NPUTF8 * const methodNames[];
+
+    InvokeResult invoke(int index, const NPVariant *args, uint32_t argCount, NPVariant &result);
+};
+
+
 class LibvlcVideoNPObject: public RuntimeNPObject
 {
 protected: