SpiderEye icon indicating copy to clipboard operation
SpiderEye copied to clipboard

Cannot load video elements as embedded resources or from local file system on Linux

Open johnvcoleman-w24 opened this issue 5 years ago • 2 comments

Before I start complaining, thank you for writing SpiderEye, you've saved me a bunch of work so far!

Describe the bug Unable to load video elements that are embedded resources on Linux.

To Reproduce Steps to reproduce the behavior:

  1. Add index.html (that contains a video element with a local src to a mp4 file) to SpiderEye.Core.App
<video class="video" autoplay muted loop style="z-index: 1;">
   <source src="background.mp4" type="video/mp4">
</video>
  1. Add the background.mp4 referenced in index.html to SpiderEye.Core.App
  2. Run the app and observe the video does not play

Expected behavior Local references to multimedia content should play normally just like content from remote uris do.

Environment:

  • OS: Linux
  • SpiderEye Version: 1.0

Debugging output from gstreamer:

0:00:00.339282760 5020 0x565438c3db60 INFO webkitglvideosink GLVideoSinkGStreamer.cpp:118:webKitGLVideoSinkConstructed: Forcing RGBA as GStreamer is not new enough. 0:00:00.367481294 5020 0x565438c3db60 INFO webkitmediaplayer MediaPlayerPrivateGStreamer.cpp:1240:setPlaybinURL: Load spidereye://resources.6uyf1fll.internal/background.mp4 0:00:00.367565817 5020 0x565438c3db60 DEBUG webkitmediaplayer MediaPlayerPrivateGStreamer.cpp:617:loadFull: preload: Auto 0:00:00.367587427 5020 0x565438c3db60 DEBUG webkitmediaplayer MediaPlayerPrivateGStreamer.cpp:1531:commitLoad: Committing load. 0:00:00.367609401 5020 0x565438c3db60 DEBUG webkitmediaplayer MediaPlayerPrivateGStreamer.cpp:1212:changePipelineState: Changing state change to PAUSED from NULL with VOID_PENDING pending 0:00:00.391341891 5020 0x565438c3db60 DEBUG webkitglvideosink GLVideoSinkGStreamer.cpp:273:webKitGLVideoSinkChangeState: NULL->READY 0:00:00.391410452 5020 0x565438c3db60 DEBUG webkitglvideosink GLVideoSinkGStreamer.cpp:158:ensureGstGLContext: Creating X11 shared GL display 0:00:00.403268273 5020 0x565438c3db60 WARN uridecodebin gsturidecodebin.c:1409:gen_source_element: error: No URI handler implemented for "spidereye".

It would appear that the spidereye:// "protocol" is unknown to gstreamer, no surprise there. So I implemented my own LocalFileContentProvider to pull the content directly from the local filesystem, and it seems to work fine. The files are found (confirmed in the debugger) but at some point after that the spidereye:// prefix is being added to the uri. I can't seem to override the Uri.Scheme to tell it it's not an embedded resource either. Perhaps I'm looking at the problem wrong.

I can send you a pull request of what I have so far for the LocalFileContentProvider, but there's nothing insightful in it. :)

Thanks!

johnvcoleman-w24 avatar Sep 15 '20 20:09 johnvcoleman-w24

Digging through the Linux specific code looking for an entry point for making mods to allow the loading of content from the local file system (and staying within your architectural framework) I came across these two lines:

https://github.com/JBildstein/SpiderEye/blob/13a58151b169ec835b18fbc631feb5b889e64229/Source/SpiderEye.Linux/GtkWebview.cs#L83-L84

const string scheme = "spidereye";
customHost = new Uri(UriTools.GetRandomResourceUrl(scheme));

This seems to be the source of the hard coded spidereye scheme in the Uri I can't override... can you give some background on lines 83-84 and the need for a random uri generator?

Thanks.

johnvcoleman-w24 avatar Sep 16 '20 14:09 johnvcoleman-w24

I'm glad you like it and also thank you for thorough bug reports like this, they can only make SpiderEye better :)

The main problem seems to be that the media player/gstreamer circumvents the usual browser loading and attempts to do load stuff by itself. Spiderye registers the spidereye protocol with webkit and handles any requests via the content provider which can load files from wherever (as you have done with the file provider).

The spidereye prefix is added because that's the URL the site was loaded from. If you request e.g. /index.hml to be loaded then SpiderEye goes ahead and opens spidereye://randomurl/index.html in the webview. Then any relative URLs on that page will also be loaded by the same root and can be handled by SpiderEye. Same thing if you open https://foo.bar in a browser, any link/resource with a relative URL will be loaded from https://foo.bar/relativeLink

The reason for the random URL is security. If I'd always use the same URL and a malicious site knowing that would be loaded in the webview, it could request resources only meant for the app. Sure, it's not a huge risk but it's easily prevented and has no downside as far as I can see.

Anyway, back to the bug: From the looks of it, gstreamer needs its own protocol handler which probably can be done with this API: https://gstreamer.freedesktop.org/documentation/gstreamer/gsturihandler.html?gi-language=c

I'll have to look into it further on how to actually use and implement that though.

JBildstein avatar Sep 17 '20 13:09 JBildstein