diff --git a/subprojects/gst-plugins-bad/sys/webview2/gstwebview2object.cpp b/subprojects/gst-plugins-bad/sys/webview2/gstwebview2object.cpp index a49dbaf409..4514490021 100644 --- a/subprojects/gst-plugins-bad/sys/webview2/gstwebview2object.cpp +++ b/subprojects/gst-plugins-bad/sys/webview2/gstwebview2object.cpp @@ -30,6 +30,7 @@ #include "gstwebview2object.h" #include #include +#include #include #include #include @@ -76,6 +77,7 @@ enum { PROP_0, PROP_DEVICE, + PROP_USER_DATA_FOLDER, }; template < typename InterfaceType, PCNZWCH runtime_class_id > static HRESULT @@ -132,7 +134,7 @@ public: STDMETHODIMP RuntimeClassInitialize (GstWebView2Object * obj, GstD3D11Device * device, - HANDLE event_handle, HWND hwnd) + HANDLE event_handle, HWND hwnd, PCWSTR user_data_folder) { obj_ = obj; device_ = device; @@ -186,6 +188,12 @@ public: hr = webview_visual_->put_IsVisible (TRUE); CHECK_HR_AND_RETURN (hr, put_IsVisible); + if (user_data_folder) { + auto option = Make(); + return CreateCoreWebView2EnvironmentWithOptions (nullptr, + user_data_folder, option.Get (), this); + } + return CreateCoreWebView2Environment (this); } @@ -712,6 +720,7 @@ struct GstWebView2ObjectPrivate ComPtr queue; GThread *main_thread = nullptr; std::string location; + std::string user_data_folder; HANDLE shutdown_begin_handle; HANDLE shutdown_end_handle; WebView2State state = WEBVIEW2_STATE_INIT; @@ -750,6 +759,13 @@ gst_webview2_object_class_init (GstWebView2ObjectClass * klass) GST_TYPE_D3D11_DEVICE, (GParamFlags) (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS))); + + g_object_class_install_property (object_class, PROP_USER_DATA_FOLDER, + g_param_spec_string ("user-data-folder", "User Data Folder", + "User data folder location. Default location is ${APP_EXE}.WebView2 " + "but can be varying depending on platform", + nullptr, (GParamFlags) (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS))); } static void @@ -801,6 +817,13 @@ gst_webview2_set_property (GObject * object, guint prop_id, case PROP_DEVICE: priv->device = (GstD3D11Device *) g_value_dup_object (value); break; + case PROP_USER_DATA_FOLDER: + { + auto udf = g_value_get_string (value); + if (udf) + priv->user_data_folder = udf; + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -820,6 +843,12 @@ gst_webview2_event_loop (GstWebView2Object * self) HANDLE waitables[] = { priv->shutdown_begin_handle, priv->shutdown_end_handle }; + gunichar2 *udf_location = nullptr; + + if (!priv->user_data_folder.empty ()) { + udf_location = g_utf8_to_utf16 (priv->user_data_folder.c_str (), + -1, nullptr, nullptr, nullptr); + } GST_D3D11_CALL_ONCE_BEGIN { WNDCLASSEXA wc = { }; @@ -864,7 +893,7 @@ gst_webview2_event_loop (GstWebView2Object * self) } hr = MakeAndInitialize < GstWebView2Item > (&priv->item, self, priv->device, - priv->shutdown_begin_handle, hwnd); + priv->shutdown_begin_handle, hwnd, (PCWSTR) udf_location); if (FAILED (hr)) { GST_ERROR_OBJECT (self, "Couldn't initialize item"); goto out; @@ -919,6 +948,8 @@ out: priv->queue = nullptr; if (hwnd) CloseWindow (hwnd); + + g_free (udf_location); } static gpointer @@ -964,14 +995,16 @@ gst_webview2_object_frame_arrived (GstWebView2Object * obj, } GstWebView2Object * -gst_webview2_object_new (GstD3D11Device * device) +gst_webview2_object_new (GstD3D11Device * device, + const std::string & user_data_folder) { GstWebView2Object *self; g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), nullptr); self = (GstWebView2Object *) - g_object_new (GST_TYPE_WEBVIEW2_OBJECT, "device", device, nullptr); + g_object_new (GST_TYPE_WEBVIEW2_OBJECT, "device", device, + "user-data-folder", user_data_folder.c_str (), nullptr); gst_object_ref_sink (self); if (self->priv->state != WEBVIEW2_STATE_RUNNING) { diff --git a/subprojects/gst-plugins-bad/sys/webview2/gstwebview2object.h b/subprojects/gst-plugins-bad/sys/webview2/gstwebview2object.h index e6685e2b3e..7fec78916b 100644 --- a/subprojects/gst-plugins-bad/sys/webview2/gstwebview2object.h +++ b/subprojects/gst-plugins-bad/sys/webview2/gstwebview2object.h @@ -31,7 +31,8 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (GstWebView2Object, gst_webview2_object, GST, WEBVIEW2_OBJECT, GstObject); -GstWebView2Object * gst_webview2_object_new (GstD3D11Device * device); +GstWebView2Object * gst_webview2_object_new (GstD3D11Device * device, + const std::string & user_data_folder); gboolean gst_webview2_object_set_location (GstWebView2Object * client, const std::string & location, diff --git a/subprojects/gst-plugins-bad/sys/webview2/gstwebview2src.cpp b/subprojects/gst-plugins-bad/sys/webview2/gstwebview2src.cpp index b1265733de..960bbdad17 100644 --- a/subprojects/gst-plugins-bad/sys/webview2/gstwebview2src.cpp +++ b/subprojects/gst-plugins-bad/sys/webview2/gstwebview2src.cpp @@ -61,6 +61,7 @@ enum PROP_LOCATION, PROP_PROCESSING_DEADLINE, PROP_JAVASCRIPT, + PROP_USER_DATA_FOLDER, }; #define DEFAULT_LOCATION "about:blank" @@ -130,6 +131,7 @@ struct GstWebView2SrcPrivate std::string location = DEFAULT_LOCATION; GstClockTime processing_deadline = DEFAULT_PROCESSING_DEADLINE; std::string script; + std::string user_data_folder; }; /* *INDENT-ON* */ @@ -205,6 +207,12 @@ gst_webview2_src_class_init (GstWebView2SrcClass * klass) nullptr, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_PLAYING))); + g_object_class_install_property (object_class, PROP_USER_DATA_FOLDER, + g_param_spec_string ("user-data-folder", "User Data Folder", + "Absolute path to WebView2 user data folder location.", nullptr, + (GParamFlags) (G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY))); + gst_element_class_set_static_metadata (element_class, "WebView2 Source", "Source/Video", "Creates a video stream rendered by WebView2", @@ -314,6 +322,15 @@ gst_webview2_src_set_property (GObject * object, guint prop_id, } break; } + case PROP_USER_DATA_FOLDER: + { + auto udf = g_value_get_string (value); + if (udf) + priv->user_data_folder = udf; + else + priv->user_data_folder.clear (); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -341,6 +358,9 @@ gst_win32_video_src_get_property (GObject * object, guint prop_id, case PROP_JAVASCRIPT: g_value_set_string (value, priv->script.c_str ()); break; + case PROP_USER_DATA_FOLDER: + g_value_set_string (value, priv->script.c_str ()); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -417,7 +437,7 @@ gst_webview2_src_start (GstBaseSrc * src) GST_DEBUG_OBJECT (self, "D3D12 copy support: %d", priv->can_d3d12_copy); std::lock_guard < std::mutex > lk (priv->lock); - priv->object = gst_webview2_object_new (priv->device); + priv->object = gst_webview2_object_new (priv->device, priv->user_data_folder); if (!priv->object) { GST_ERROR_OBJECT (self, "Couldn't create object"); return FALSE;