diff --git a/.gitignore b/.gitignore index 9a76c30a2383188cb54012cac2c0a6d7780d91b5..b4260785ae0f4a63844803ce25b5bf563997ec36 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ experimental.js experimental.wasm experimental.wasm.map experimental.worker.js +experimental.nativefs_worker.js diff --git a/compile.sh b/compile.sh index 4e149418260851b1528fbdd1ddeea95d0520966e..3eadfabce1c538c1f7961780bd80457c64299b4f 100755 --- a/compile.sh +++ b/compile.sh @@ -47,8 +47,8 @@ if [ ! -d vlc ]; then git am -3 ../vlc_patches/video_output/00*.patch git am -3 ../vlc_patches/logger/00*.patch git am -3 ../vlc_patches/0001-vlc.js-modules-remove-category.patch + git am -3 ../vlc_patches/filesystem/0001-access-initial-emscripten-nativefs-support.patch git am -3 ../vlc_patches/audio_output/new_aout.patch - # git am -3 ../vlc_patches/filesystem/*.patch fi checkfail "vlc source: git clone failed" fi diff --git a/create_main.sh b/create_main.sh index f997c6d1f62b9cae6b22a351a8cbda4c767f6041..a7e02423663fdddf5b4f3a7b2fc7b70da4b6a171 100755 --- a/create_main.sh +++ b/create_main.sh @@ -34,6 +34,7 @@ emcc --bind -s USE_PTHREADS=1 -s TOTAL_MEMORY=1GB -s PTHREAD_POOL_SIZE=15 \ -s MODULARIZE=1 -s EXPORT_NAME="VlcModule" \ -s EXPORTED_RUNTIME_METHODS="allocateUTF8" \ -I $PATH_VLC/include/ \ + -s EMSCRIPTEN_NATIVE_FS=1 \ main.c exports_media_player.c exports_media.c \ $PATH_VLC/build-emscripten/lib/.libs/libvlc.a \ $PATH_VLC/build-emscripten/vlc-modules.bc \ @@ -43,4 +44,4 @@ emcc --bind -s USE_PTHREADS=1 -s TOTAL_MEMORY=1GB -s PTHREAD_POOL_SIZE=15 \ $PATH_VLC/build-emscripten/compat/.libs/libcompat.a \ --js-library lib/wasm-imports.js \ --js-library vlc/modules/audio_output/webaudio/webaudio.js \ - -o experimental.js --preload-file ${SAMPLE_DIR} + -o experimental.js diff --git a/exports_media.c b/exports_media.c index 55d35e13faaf4050bd3b82f9b187c9336b6bf010..2e74cb5e5f75674b6de5a6a656cde5f5eb75d86f 100644 --- a/exports_media.c +++ b/exports_media.c @@ -14,6 +14,10 @@ libvlc_media_t* EMSCRIPTEN_KEEPALIVE wasm_media_new_path(const char *path) { return libvlc_media_new_path(libvlc, path); } +libvlc_media_t* EMSCRIPTEN_KEEPALIVE wasm_media_new_location(const char *path) { + return libvlc_media_new_location(libvlc, path); +} + void EMSCRIPTEN_KEEPALIVE wasm_media_retain( libvlc_media_t *media) { libvlc_media_retain(media); } diff --git a/lib/libvlc.js b/lib/libvlc.js index 51a8e4d2bbd5a2d4813d400b3c765896a8505717..a46b4b8f005dd1e418e8d82bf35cb69a003be7ce 100644 --- a/lib/libvlc.js +++ b/lib/libvlc.js @@ -228,7 +228,7 @@ export class Media { this.module = module; let path_ptr = module.allocateUTF8(path) - this.media_ptr = module._wasm_media_new_path(path_ptr); + this.media_ptr = module._wasm_media_new_location(path_ptr); module._free(path_ptr); if (this.media_ptr == 0) { diff --git a/main.c b/main.c index d6431c5dd554c443a76a0d17dc160ed72ac77ae8..adfd0086a3dbbb2f7eae7f189641bbcddfab3d9a 100644 --- a/main.c +++ b/main.c @@ -6,6 +6,7 @@ #include <emscripten.h> #include <emscripten/html5.h> +#include <emscripten/nativefs.h> libvlc_media_player_t *mp; libvlc_instance_t *libvlc; @@ -47,6 +48,7 @@ int main() { * If this thread stop, all proxyfied functions wont be called. */ EM_ASM(Module['noExitRuntime']=true); + nativefs_init("#btn"); char const *vlc_argv[] = { "-vvv", "--no-spu", diff --git a/vlc.html b/vlc.html index 345f3f898b2ab474369d829610a681b59578094f..c4a55ed3b3c125ba0dca40cfe4f8d7d39ab7868c 100644 --- a/vlc.html +++ b/vlc.html @@ -96,7 +96,7 @@ width=1280 height=720 ></canvas> </div> - + <button id="btn">Press Me</button> <script src="./lib/module-loader.js"></script> <script src="./experimental.js"></script> @@ -121,7 +121,7 @@ }; const overlay = document.getElementById("overlay"); - const media_player = new MediaPlayer(Module, "./samples/BigBuckBunny.mp4"); + const media_player = new MediaPlayer(Module, "emscriptenfs:///mediafile"); media_player.set_volume(80); // FIXME diff --git a/vlc_patches/filesystem/0001-access-initial-emscripten-nativefs-support.patch b/vlc_patches/filesystem/0001-access-initial-emscripten-nativefs-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..a88d4105ca8769142f9e1cfc086d1ac0c05ed196 --- /dev/null +++ b/vlc_patches/filesystem/0001-access-initial-emscripten-nativefs-support.patch @@ -0,0 +1,190 @@ +From 8616dbdcb2035c2d1d724b27fb7c7bc0258f5b71 Mon Sep 17 00:00:00 2001 +From: Mehdi Sabwat <mehdi@videolabs.io> +Date: Wed, 18 Nov 2020 17:50:39 +0100 +Subject: [PATCH 1/2] access: initial emscripten nativefs support + +--- + modules/access/Makefile.am | 8 ++ + modules/access/emscripten.cpp | 154 ++++++++++++++++++++++++++++++++++ + 2 files changed, 162 insertions(+) + create mode 100644 modules/access/emscripten.cpp + +diff --git a/modules/access/Makefile.am b/modules/access/Makefile.am +index 2f5af78202..0c6d48f778 100644 +--- a/modules/access/Makefile.am ++++ b/modules/access/Makefile.am +@@ -463,3 +463,11 @@ librist_plugin_la_LIBADD = $(RIST_LIBS) $(SOCKET_LIBS) $(LIBPTHREAD) + librist_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(accessdir)' + access_LTLIBRARIES += $(LTLIBrist) + EXTRA_LTLIBRARIES += librist_plugin.la ++ ++### EMSCRIPTEN ### ++ ++libemscriptenfs_plugin_la_SOURCES = access/emscripten.cpp ++libemscriptenfs_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) ++if HAVE_EMSCRIPTEN ++access_LTLIBRARIES += libemscriptenfs_plugin.la ++endif +diff --git a/modules/access/emscripten.cpp b/modules/access/emscripten.cpp +new file mode 100644 +index 0000000000..2b0f3c833b +--- /dev/null ++++ b/modules/access/emscripten.cpp +@@ -0,0 +1,154 @@ ++/***************************************************************************** ++ * emscripten.cpp: emscripten file system access plugin ++ ***************************************************************************** ++ * Copyright (C) 2022 VLC authors, VideoLAN and Videolabs ++ * ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Lesser General Public License as published by ++ * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser 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. ++ *****************************************************************************/ ++ ++#ifdef HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++#include <vlc_common.h> ++#include <vlc_plugin.h> ++#include<vlc_stream.h> ++#include <emscripten.h> ++#include <emscripten/nativefs.h> ++ ++static ssize_t Read (stream_t *, void *, size_t); ++static int FileSeek (stream_t *, uint64_t); ++static int FileControl (stream_t *, int, va_list); ++ ++typedef struct ++{ ++ int fd; ++ ++ bool b_pace_control; ++} access_sys_t; ++ ++/***************************************************************************** ++ * FileOpen: open the file ++ *****************************************************************************/ ++int FileOpen( vlc_object_t *p_this ) ++{ ++ stream_t *p_access = reinterpret_cast<stream_t *>(p_this); ++ ++ /* Open file */ ++ /* ++ Setting the default fd to 3, the first valid file descriptor. ++ */ ++ int fd = 3; ++ access_sys_t *p_sys = reinterpret_cast<access_sys_t *>(vlc_obj_malloc(p_this, sizeof (*p_sys))); ++ if (unlikely(p_sys == NULL)) ++ goto error; ++ p_access->pf_read = Read; ++ p_access->pf_block = NULL; ++ p_access->pf_control = FileControl; ++ p_access->p_sys = p_sys; ++ p_sys->fd = fd; ++ p_access->pf_seek = FileSeek; ++ p_sys->b_pace_control = strcasecmp (p_access->psz_name, "stream"); ++ ++ // FIX ME: calling this from the main application for now ++ // nativefs_init(1, "#btn"); ++ ++ return VLC_SUCCESS; ++error: ++ return VLC_EGENERIC; ++} ++ ++void FileClose (vlc_object_t * p_this) ++{ ++ stream_t *p_access = reinterpret_cast<stream_t *>(p_this); ++ ++ access_sys_t *sys = reinterpret_cast<access_sys_t *>(p_access->p_sys); ++ nativefs_seek(sys->fd, 0, NATIVEFS_SEEK_SET); ++} ++ ++static ssize_t Read (stream_t *p_access, void *p_buffer, size_t i_len) ++{ ++ access_sys_t *sys = reinterpret_cast<access_sys_t *>(p_access->p_sys); ++ ++ size_t size = nativefs_read(sys->fd, p_buffer, i_len); ++ return size; ++} ++ ++/***************************************************************************** ++ * Seek: seek to a specific location in a file ++ *****************************************************************************/ ++static int FileSeek (stream_t *p_access, uint64_t i_pos) ++{ ++ access_sys_t *sys = reinterpret_cast<access_sys_t *>(p_access->p_sys); ++ ++ nativefs_seek(sys->fd, (size_t)i_pos, NATIVEFS_SEEK_SET); ++ return VLC_SUCCESS; ++} ++ ++/***************************************************************************** ++ * Control: ++ *****************************************************************************/ ++static int FileControl( stream_t *p_access, int i_query, va_list args ) ++{ ++ access_sys_t *sys = reinterpret_cast<access_sys_t *>(p_access->p_sys); ++ bool *pb_bool; ++ vlc_tick_t *pi_64; ++ ++ switch( i_query ) ++ { ++ case STREAM_CAN_SEEK: ++ case STREAM_CAN_FASTSEEK: ++ pb_bool = va_arg( args, bool * ); ++ *pb_bool = false; ++ break; ++ case STREAM_CAN_PAUSE: ++ case STREAM_CAN_CONTROL_PACE: ++ pb_bool = va_arg( args, bool * ); ++ *pb_bool = sys->b_pace_control; ++ break; ++ case STREAM_GET_SIZE: ++ { ++ /* ++ sys->fd - 3 because the table that holds the files starts ++ at 0 ++ */ ++ size_t size = (size_t) MAIN_THREAD_EM_ASM_INT({ ++ return NATIVEFS.files[0].fileSize; ++ }, sys->fd - 3); ++ *va_arg( args, uint64_t * ) = size; ++ break; ++ } ++ case STREAM_GET_PTS_DELAY: ++ pi_64 = va_arg( args, vlc_tick_t * ); ++ // network caching for later ++ *pi_64 = VLC_TICK_FROM_MS( ++ var_InheritInteger (p_access, "file-caching") ); ++ break; ++ default: ++ return VLC_EGENERIC; ++ ++ } ++ return VLC_SUCCESS; ++} ++ ++vlc_module_begin () ++ set_description( N_("File input") ) ++ set_shortname( N_("emscriptenfs") ) ++ set_subcategory( SUBCAT_INPUT_ACCESS ) ++ set_capability( "access", 50 ) ++ add_shortcut( "emscriptenfs" ) ++ set_callbacks( FileOpen, FileClose ) ++vlc_module_end () +-- +2.34.1 +