]> git.sesse.net Git - vlc/commitdiff
* New Lua based playlist demuxer. Code is far from being finished. It currently imple...
authorAntoine Cellerier <dionoea@videolan.org>
Sun, 13 May 2007 21:52:20 +0000 (21:52 +0000)
committerAntoine Cellerier <dionoea@videolan.org>
Sun, 13 May 2007 21:52:20 +0000 (21:52 +0000)
configure.ac
modules/demux/playlist/Modules.am
modules/demux/playlist/luaplaylist.c [new file with mode: 0644]
share/luaplaylist/test.lua [new file with mode: 0644]

index b6eff1567ddbbb8f34b0bc8459b70e1710c304e4..9082d62060cfc67c1b805b3e91e0abbb4e906d61 100644 (file)
@@ -1532,6 +1532,20 @@ if test "${enable_shout}" = "yes"; then
     [AC_MSG_WARN(libshout library not found)])
 fi
 
+dnl Lua playlist demux
+AC_ARG_ENABLE(luaplaylist,
+  [  --enable-lua            lua playlist demux plugin (default enabled)])
+if test "${enable_lua}" != "no"
+then
+  PKG_CHECK_MODULES(LUA, lua5.1,
+    [ AC_DEFINE(HAVE_LUA, [], [Define if you have the lua library])
+      VLC_ADD_PLUGINS([luaplaylist])
+      VLC_ADD_LDFLAGS([luaplaylist],[$LUA_LIBS])
+      VLC_ADD_CFLAGS([luaplaylist],[$LUA_CFLAGS])
+    ],
+    [AC_MSG_WARN(lua 5.0 not found)])
+fi
+
 dnl
 dnl HTTP daemon
 dnl
index c8cb97521af19606832953de8aede429bb0479e7..8ad6a6f75e720b08aaadf2937398b301a549cf9d 100644 (file)
@@ -17,4 +17,4 @@ SOURCES_playlist = \
        videoportals.c \
        $(NULL)
 
-
+SOURCES_luaplaylist = luaplaylist.c
diff --git a/modules/demux/playlist/luaplaylist.c b/modules/demux/playlist/luaplaylist.c
new file mode 100644 (file)
index 0000000..3eb315d
--- /dev/null
@@ -0,0 +1,238 @@
+/*****************************************************************************
+ * luaplaylist.c :  Lua playlist demux module
+ *****************************************************************************
+ * Copyright (C) 2007 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Antoine Cellerier <dionoea at videolan tod org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc_demux.h>
+#include <vlc_url.h>
+#include <vlc_strings.h>
+
+#include <errno.h>                                                 /* ENOMEM */
+#include "playlist.h"
+
+#include <lua.h>        /* Low level lua C API */
+#include <lauxlib.h>    /* Higher level C API */
+#include <lualib.h>     /* Lua libs */
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int E_(Import_LuaPlaylist)( vlc_object_t *p_this );
+static void E_(Close_LuaPlaylist)( vlc_object_t *p_this );
+
+static int Demux( demux_t *p_demux );
+static int Control( demux_t *p_demux, int i_query, va_list args );
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+vlc_module_begin();
+    add_shortcut( "lua" );
+    set_category( CAT_INPUT );
+    set_subcategory( SUBCAT_INPUT_DEMUX );
+
+    set_shortname( _("Lua Playlist") );
+    set_description( _("Lua Playlist Parser Interface") );
+    set_capability( "demux2", 0 );
+    set_callbacks( E_(Import_LuaPlaylist), E_(Close_LuaPlaylist) );
+vlc_module_end();
+
+/*****************************************************************************
+ *
+ *****************************************************************************/
+struct demux_sys_t
+{
+    lua_State *p_state;
+};
+
+static demux_t *vlclua_get_demux( lua_State *p_state )
+{
+    demux_t *p_demux;
+    lua_getglobal( p_state, "vlc" );
+    lua_getfield( p_state, lua_gettop( p_state ), "private" );
+    p_demux = (demux_t*)lua_topointer( p_state, lua_gettop( p_state ) );
+    lua_pop( p_state, 2 );
+    return p_demux;
+}
+
+static int vlclua_peek( lua_State *p_state )
+{
+    demux_t *p_demux = vlclua_get_demux( p_state );
+    int i = lua_gettop( p_state );
+    int n;
+    byte_t *p_peek;
+    int i_peek;
+    if( !i ) return 0;
+    n = lua_tonumber( p_state, 1 );
+    lua_pop( p_state, i );
+    i_peek = stream_Peek( p_demux->s, &p_peek, n );
+    lua_pushnumber( p_state, i_peek );
+    lua_pushlstring( p_state, (const char *)p_peek, i_peek );
+    return 2;
+}
+
+static int vlclua_readline( lua_State *p_state )
+{
+    demux_t *p_demux = vlclua_get_demux( p_state );
+    char *psz_line = stream_ReadLine( p_demux->s );
+    lua_pushstring( p_state, psz_line );
+    return 1;
+}
+
+static int vlclua_decode_uri( lua_State *p_state )
+{
+    int i = lua_gettop( p_state );
+    if( !i ) return 0;
+    const char *psz_cstring = lua_tostring( p_state, 1 );
+    if( !psz_cstring ) return 0;
+    char *psz_string = strdup( psz_cstring );
+    lua_pop( p_state, i );
+    decode_URI( psz_string );
+    lua_pushstring( p_state, psz_string );
+    free( psz_string );
+    return 1;
+}
+
+/*****************************************************************************
+ * Import_LuaPlaylist: main import function
+ *****************************************************************************/
+int E_(Import_LuaPlaylist)( vlc_object_t *p_this )
+{
+    demux_t *p_demux = (demux_t *)p_this;
+    lua_State *p_state;
+
+    p_demux->p_sys = (demux_sys_t*)malloc( sizeof( demux_sys_t ) );
+    if( !p_demux->p_sys )
+    {
+        return VLC_ENOMEM;
+    }
+
+    p_demux->pf_control = Control;
+    p_demux->pf_demux = Demux;
+
+    /* Initialise Lua state structure */
+    p_state = luaL_newstate();
+    if( !p_state )
+    {
+        msg_Err( p_demux, "Could not create new Lua State" );
+        free( p_demux->p_sys );
+        return VLC_EGENERIC;
+    }
+    p_demux->p_sys->p_state = p_state;
+
+    /* Load Lua libraries */
+    luaL_openlibs( p_state ); /* FIXME: Don't open all the libs? */
+
+    static luaL_Reg p_reg[] =
+    {
+        { "readline", vlclua_readline },
+        { "peek", vlclua_peek },
+        { "decode_uri", vlclua_decode_uri }
+    };
+
+    luaL_register( p_state, "vlc", p_reg );
+    lua_pushlightuserdata( p_state, p_demux );
+    lua_setfield( p_state, lua_gettop( p_state ) - 1, "private" );
+    lua_pushstring( p_state, p_demux->psz_path );
+    lua_setfield( p_state, lua_gettop( p_state ) - 1, "path" );
+    lua_pushstring( p_state, p_demux->psz_access );
+    lua_setfield( p_state, lua_gettop( p_state ) - 1, "access" );
+
+    lua_pop( p_state, 1 );
+
+    {
+        const char *psz_filename = "share/luaplaylist/test.lua";
+        int i_ret;
+
+        /* Load and run the script(s) */
+        if( luaL_dofile( p_state, psz_filename ) )
+        {
+            msg_Warn( p_demux, "Error while runing script %s: %s", psz_filename, lua_tostring( p_state, lua_gettop( p_state ) ) );
+            return VLC_EGENERIC;
+        }
+
+        if( lua_gettop( p_state ) )
+        {
+            i_ret = lua_toboolean( p_state, 1 );
+            printf( "Script returned %d: %d\n", 1, i_ret );
+
+            while( lua_gettop( p_state ) != 1 )
+            {
+                printf( "Script returned %d: %s\n", lua_gettop( p_state ),
+                        lua_tostring( p_state, lua_gettop( p_state ) ) );
+                lua_pop( p_state, 1 );
+            }
+
+            lua_pop( p_state, 1 );
+
+            if( !i_ret )
+            {
+                E_(Close_LuaPlaylist)( p_this );
+                return VLC_EGENERIC;
+            }
+        }
+        else
+        {
+            E_(Close_LuaPlaylist)( p_this );
+            return VLC_EGENERIC;
+        }
+    }
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Deactivate: frees unused data
+ *****************************************************************************/
+void E_(Close_LuaPlaylist)( vlc_object_t *p_this )
+{
+    demux_t *p_demux = (demux_t *)p_this;
+    lua_close( p_demux->p_sys->p_state );
+    free( p_demux->p_sys );
+}
+
+static int Demux( demux_t *p_demux )
+{
+    /*input_item_t *p_input;*/
+
+    INIT_PLAYLIST_STUFF;
+
+#if 0
+    p_input = input_ItemNewExt( p_playlist, psz_url, psz_title, 0, NULL, -1 );
+    playlist_BothAddInput( p_playlist, p_input,
+                           p_item_in_category,
+                           PLAYLIST_APPEND | PLAYLIST_SPREPARSE,
+                           PLAYLIST_END, NULL, NULL, VLC_FALSE );
+#endif
+
+    HANDLE_PLAY_AND_RELEASE;
+
+    return -1; /* Needed for correct operation of go back */
+}
+
+static int Control( demux_t *p_demux, int i_query, va_list args )
+{
+    return VLC_EGENERIC;
+}
diff --git a/share/luaplaylist/test.lua b/share/luaplaylist/test.lua
new file mode 100644 (file)
index 0000000..1e7a9e4
--- /dev/null
@@ -0,0 +1,75 @@
+-- $Id$
+
+if vlc.access ~= "http"
+then
+       return false
+end 
+
+url = nil
+title = nil
+
+function get_url_param( url, name )
+       return string.gsub( vlc.path, "^.*"..name.."=([^&]*).*$", "%1" )
+end
+
+if string.match( vlc.path, "youtube.com" ) 
+then
+       if string.match( vlc.path, "watch%?v=" )
+       then
+               url = string.gsub( vlc.path, "^(.*)watch%?v=([^&]*).*$", "http://%1v/%2" )
+               while not title
+               do
+                       line = vlc.readline()
+                       if not line
+                       then
+                               break
+                       end
+                       if string.match( line, "<meta name=\"title\"" )
+                       then
+                               title = string.gsub( line, "^.*content=\"([^\"]*).*$", "%1" )
+                       end
+               end
+       elseif string.match( vlc.path, "watch_fullscreen%?video_id=" ) or string.match( vlc.path, "p.swf" ) or string.match( vlc.path, "player2.swf" )
+       then
+               video_id = get_url_param( vlc.path, "video_id" )
+               t = get_url_param( vlc.path, "t" )
+               url = "http://www.youtube.com/get_video.php?video_id="..video_id.."&t="..t
+               if string.match( vlc.path, "title=" )
+               then
+                       title = get_url_param( vlc.path, "title" )
+               end
+       end
+elseif string.match( vlc.path, "dailymotion.com" )
+then
+       len, str = vlc.peek( 9 )
+       if str == "<!DOCTYPE"
+       then
+               while not url
+               do
+                       line = vlc.readline()
+                       if string.match( line, "param name=\"flashvars\" value=\"url=" )
+                       then
+                               url = vlc.decode_uri( string.gsub( line, "^.*param name=\"flashvars\" value=\"url=([^&]*).*$", "%1" ) )
+                       end
+               end
+       end
+elseif string.match( vlc.path, "video.google.com" ) and string.match( vlc.path, "videoplay" )
+then
+       url = string.gsub( vlc.path, "^.*(docid=[^&]*).*$", "http://video.google.com/videogvp?%1" )
+elseif string.match( vlc.path, "metacafe.com" )
+then
+       if string.match( vlc.path, "watch/" )
+       then
+               url = string.gsub( vlc.path, "^.*watch/(.*[^/])/?$", "http://www.metacafe.com/fplayer/%1.swf" )
+       elseif string.match( vlc.path, "mediaURL=" )
+       then
+               url = string.gsub( vlc.path, "^.*mediaURL=([^&]*).*$", "%1" )
+       end
+end
+
+if url == nil
+then
+       return false
+else
+       return true, url, title
+end