Rafostar / gtuber

C library to fetch media info from websites
https://rafostar.github.io/gtuber/
GNU Lesser General Public License v2.1
9 stars 3 forks source link

gtuber not picked up by clapper #33

Closed josch closed 1 year ago

josch commented 1 year ago

Hi,

I compiled and installed gtuber from git:

$ gst-inspect-1.0 gtuber
Plugin Details:
  Name                     gtuber
  Description              Gtuber elements
  Filename                 /usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstgtuber.so
  Version                  0.4.0
  License                  LGPL
  Source module            gtuber
  Binary package           gst-plugin-gtuber
  Origin URL               https://github.com/Rafostar/gtuber

  gtuberdashdemux: Gtuber DASH demuxer
  gtuberhlsdemux: Gtuber HLS demuxer
  gtubersrc: Gtuber source
  gtuberuridemux: Gtuber URI demuxer

  4 features:
  +-- 4 elements

But running clapper with GST_PLUGIN_FEATURE_RANK=gtubersrc:300 produces:

(com.github.rafostar.Clapper:93726): Clapper-CRITICAL **: 05:10:32.757: Error from element /GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: Your GStreamer installation is missing a plug-in.
Your GStreamer installation is missing a plug-in.
../gst/playback/gsturidecodebin.c(1027): no_more_pads_full (): /GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0:
no suitable plugins found:
../gst/playback/gstdecodebin2.c(4701): gst_decode_bin_expose (): /GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0:
no suitable plugins found:
Missing decoder: text/html (text/html)

How can I further debug this problem?

Rafostar commented 1 year ago

Check output of:

GST_DEBUG=*gtuber*:7 G_MESSAGES_DEBUG=Gtuber clapper "$URI"

where "$URI" is a link to video page on one of supported video services (e.g. Twitch).

josch commented 1 year ago

Thank you! Here is the output:

$ GST_DEBUG=*gtuber*:7 G_MESSAGES_DEBUG=Gtuber GST_PLUGIN_FEATURE_RANK=gtubersrc:300 clapper https://youtu.be/Q039wMmYRUY
0:00:00.596906248 105092 0x5591d56d9120 DEBUG              gtubersrc gstgtubersrc.c:946:_obtain_available_protocols: Checking supported by gtuber URI schemes
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.799: Initializing cache
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.799: Opening cache file for reading: /home/josch/.cache/gtuber-0.0/gtuber_cache.bin
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.799: Cache header, name: GTUBER, version_hex: 262144
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.799: Cache opened successfully
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Config dir path: /home/josch/.config/gtuber-0.0
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Config compared, mod_time: 0 == 0, n_files: 0 == 0
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Read cache dir path: /usr/lib/x86_64-linux-gnu/gtuber-0.0
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Cache compared, mod_time: 1667010821 == 1667010821, n_plugins: 7 == 7
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Reading plugins compat data for dir: /usr/lib/x86_64-linux-gnu/gtuber-0.0
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Read compat data for 7 plugins
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Initialized cache
0:00:00.597941580 105092 0x5591d56d9120 INFO               gtubersrc gstgtubersrc.c:963:_obtain_available_protocols: Added supported URI scheme: http
0:00:00.597962590 105092 0x5591d56d9120 INFO               gtubersrc gstgtubersrc.c:963:_obtain_available_protocols: Added supported URI scheme: https
0:00:00.597972251 105092 0x5591d56d9120 INFO               gtubersrc gstgtubersrc.c:963:_obtain_available_protocols: Added supported URI scheme: lbry
0:00:00.597991013 105092 0x5591d56d9120 INFO               gtubersrc gstgtubersrc.c:963:_obtain_available_protocols: Added supported URI scheme: peertube
0:00:00.597999078 105092 0x5591d56d9120 INFO               gtubersrc gstgtubersrc.c:963:_obtain_available_protocols: Added supported URI scheme: gtuber
0:00:00.598114773 105092 0x5591d56d9120 DEBUG              gtubersrc gstgtubersrc.c:292:gst_gtuber_src_set_location:<source> Changing location to: https://youtu.be/Q039wMmYRUY
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Checking URI support: https://youtu.be/Q039wMmYRUY
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Searching for plugin that opens URI: https://youtu.be/Q039wMmYRUY
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Cache query, scheme: "https", host: "youtu.be"
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.800: Searching in cached dir: /usr/lib/x86_64-linux-gnu/gtuber-0.0
(com.github.rafostar.Clapper:105092): Gtuber-DEBUG: 12:10:45.801: URI supported: no
0:00:00.598461258 105092 0x5591d56d9120 TRACE              gtubersrc gstgtubersrc.c:174:gst_gtuber_src_finalize: Finalize

(com.github.rafostar.Clapper:105092): Clapper-CRITICAL **: 12:10:46.175: Error from element /GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0: Your GStreamer installation is missing a plug-in.
Your GStreamer installation is missing a plug-in.
../gst/playback/gsturidecodebin.c(1027): no_more_pads_full (): /GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0:
no suitable plugins found:
../gst/playback/gstdecodebin2.c(4701): gst_decode_bin_expose (): /GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstDecodeBin:decodebin0:
no suitable plugins found:
Missing decoder: text/html (text/html)
Rafostar commented 1 year ago

As you can see it's picked up correctly. Gtuber is a modular API where it's modules (plugins) add per site support. It seems to me that you simply do not have YouTube plugin compiled (probably due to unsatisfied dependency if you were compiling with auto). You can see which plugins are going to be compiled when preparing build directory in meson summary output. We currently have a total of 10 while you have 7 installed here.

Also, if all you want is play some videos with Clapper, then I recommend Flatpak version of it. It ships this whole thing inside and unfortunately GStreamer has few bugs in its DASH support, thus gtuber provided GStreamer plugin is not going to work correctly for sites that use DASH anyway (again I patch it in Flatpak). Sites that use HLS should work correctly through (like twitch).

josch commented 1 year ago

Aha! Indeed, in my build log it says:

  Plugins
    bilibili        : Yes
    crunchyroll-beta: No
    invidious       : Yes
    lbry            : Yes
    niconico        : No
    peertube        : Yes
    piped           : Yes
    reddit          : Yes
    twitch          : Yes
    youtube         : No

Adding json-glib and xml2 fixed this and now all plugins are built. Is there a build flag that forces all plugins to be compiled so that the build will error out if any build dependencies are missing?

The reason I'm not using the flatpak version is, that I'm considering packaging gtuber for Debian where I am already maintaining clapper: https://tracker.debian.org/pkg/clapper

After rebuilding gtuber I tried it out again and it works like a charm, thank you! I have some questions though:

Also, since this is working fine, I would be happy to finish packaging gtuber for Debian. Could you add a git tag to gtuber on github? Having a version tagged is making packaging much easier!

Thank you for your time and for your software! I've used mpv as a video player in the past and switched to clapper because my new ARM laptop is too slow for 1080p@60 h264 video decoding in software. With gstreamer, the hardware decoder is used and that works well with only 10% cpu utilization and no frame drops. :)

sp1ritCS commented 1 year ago

Aha! Indeed, in my build log it says:

  Plugins
    bilibili        : Yes
    crunchyroll-beta: No
    invidious       : Yes
    lbry            : Yes
    niconico        : No
    peertube        : Yes
    piped           : Yes
    reddit          : Yes
    twitch          : Yes
    youtube         : No

Adding json-glib and xml2 fixed this and now all plugins are built. Is there a build flag that forces all plugins to be compiled so that the build will error out if any build dependencies are missing?

meson has a --auto-features=enabled flag, that forces all features (unless otherwise instructed) to be enabled. I'm actually somewhat surprised that debhelper doesn't add that flag automatically. I'd advice against overriding dh_auto_configure for each package and instead looking into adding it to debhelper itself, so that every package could profit from it.

Rafostar commented 1 year ago

Is there a build flag that forces all plugins to be compiled so that the build will error out if any build dependencies are missing?

As mentioned above (thanks @sp1ritCS ;-) ), easiest for forcing everything is probably with -Dauto_features=enabled or if you want to only guarantee some of plugins then -Dyoutube=enabled and so on.

for Debian where I am already maintaining clapper

Thanks for maintaining Clapper DEB package, btw. :-) If you have any questions/problems feel free to ask on Clapper matrix channel.

After rebuilding gtuber I tried it out again and it works like a charm

You might be mistaken here. It somewhat works, but due to GStreamer bugs it's not working correctly. I really wish the GStreamer part would work with unpatched version of GStreamer, but it's not working as it should. Many people keep asking for this and I always have to ask them to install Flaptak, as I unfortunately am not a GStreamer maintainer thus do not have permission to merge fixes that are send in MRs :-(

I've read in another issue that one should set GST_PLUGIN_FEATURE_RANK=gtubersrc:300 but it seems to work fine without that setting. Did that change?

Yes, now we cache what which of available plugins supports into binary file and on startup quickly determine which one (if any) should be loaded for user requested URI and if none we fallback into stock GStreamer functionality. This is thousands of times faster then Python based solutions (as e.g. youtube-dl). As seen in your output you were able to read cache and determine that none of the installed plugins will work thus go with fallback. All that within 1 millisecond. That's why it could be enabled by default now without slowing down other HTTP URIs.

can you point me to the gstreamer patches and to the corresponding gstreamer issue reports?

In this case I will write and pin an issue here with list of patches and what they fix. I will try to find some free time for this tomorrow.

even with unpatched gstreamer, youtube and twitch work fine

Only sites that use DASH have problems (since that's where GStreamer bugs are). Twitch uses HLS so it should work fine. Currently some of the sites that proxy youtube (e.g. Piped) won't work at all and in case of YouTube, it works but without one patch we hit connection throttling problems which causes constant switches to lower quality or being stuck at buffering.

Could you add a git tag to gtuber on github?

Not sure if this is tag material. First of all until 1.0 this should be considered unstable API. Second, since it scrapes some web pages and reverse engineers their API, what works in today version might stop working tomorrow.

josch commented 1 year ago

meson has a --auto-features=enabled flag, that forces all features (unless otherwise instructed) to be enabled. I'm actually somewhat surprised that debhelper doesn't add that flag automatically.

Thank you, that works! I now found other stuff that I hadn't built by the way of helpful error messages:

../gtuber/meson.build:174:0: ERROR: Program 'vapigen' not found or not executable

I'd advice against overriding dh_auto_configure for each package and instead looking into adding it to debhelper itself, so that every package could profit from it.

Since Debian tries to always build everything that seems reasonable as a default option, yes. I just brought up the idea on #debian-devel.

josch commented 1 year ago

Could you add a git tag to gtuber on github? Not sure if this is tag material. First of all until 1.0 this should be considered unstable API. Second, since it scrapes some web pages and reverse engineers their API, what works in today version might stop working tomorrow.

If there are no versions, then I'll have to regularly package the latest git commit. This has several disadvantages:

  1. without reading the commit log I do not know when it makes sense to package another snapshot
  2. I'll not get notified once some meaningful feature gets added or an important bug gets fixed unless I subscribe to all commits as they happen
  3. the version numbers will have to include the date and the git commit hash which makes the version numbers long and ugly

For software that accesses remote unstable APIs, other projects usually choose a date-based version, for example in iso8601 format, like 2022-10-29 for today. You could create a tag every time something meaningful (like a new backend) got added or once a backend that broke was fixed again. This would make it easier for me because I would only need to monitor the git tags and then update the packaging once a new tag appears. I agree that semantic versioning doesn't make much sense if anything can break any time by a random website deciding to change their interface.

Rafostar commented 1 year ago

If there are no versions, then I'll have to regularly package the latest git commit. This has several disadvantages.

To be honest, ideally you wouldn't want to ship half-broken package as stable version anyway. Date versioning seems best here indeed, but I was hoping to do that after API goes stable (ver. 1.0). Was also hoping, that GStreamer will have their stuff fixed by then, but they remain quiet :man_shrugging:

josch commented 1 year ago

To be honest, ideally you wouldn't want to ship half-broken package as stable version anyway. Date versioning seems best here indeed, but I was hoping to do that after API goes stable (ver. 1.0). Was also hoping, that GStreamer will have their stuff fixed by then, but they remain quiet man_shrugging

I'm looking forward to your list of gstreamer patches. In another project we are maintaining a Debian fork so we are free to build some packages like gstreamer with patches even if the gstreamer or Debian maintainers don't agree with the patches or are too slow to apply them. Thus, I'd like to try those out! :)

Do you plan to put out a git tag any time soon? My packaging is done and depending on your answer I'd either package a git snapshot first or wait for your git tag. :)

In any case, I think this issue can be more than closed. Thanks a lot for your help!

Rafostar commented 1 year ago

@josch

I opened and pinned issue with list of currently applied patches on this project github.

Do you plan to put out a git tag any time soon?

I am not sure. Currently I would prefer to go with the tagging after I can consider this a stable API, so not right now. Sorry.

My packaging is done

Not gonna interfere with you packaging. But I will give a few suggestions:

  1. Consider packaging gstreamer plugin (gst-plugin-gtuber) seperately, this way apps that want to use only our extractor won't have to pull whole gstreamer with them. Currently there are none probably, but might be worth considering anyway.
  2. If you are working with some very low-end ARM hard disk space limited machine, it is possible to package plugins separately (even each in its own package), but this might be an overkill for both you and hard for explaining to people that they have to install them one by one from the ones they care about.
  3. I know that Debian likes testing stuff, but you shouldn't run plugins test on build. They won't run if GITHUB_ACTIONS env is present. Might be easier to set when building then patching stuff to disable them.

As far as I see, all your other questions were answered here earlier. If you have something else to ask, feel free to drop and ask me directly on Clapper matrix channel (those 2 projects are somewhat related, so its also fine asking gtuber questions there too).

josch commented 1 year ago

I opened and pinned issue with list of currently applied patches on this project github

Thank you! I'll try out gstreamer with those three patches applied.

I am not sure. Currently I would prefer to go with the tagging after I can consider this a stable API, so not right now. Sorry.

No problem! I now packaged gtuber with version 0.0+git20221030.15f63bb so that whatever versioning scheme you end up using later will very likely be of a higher version than that. :)

I'm looking forward to your first git tag!

Not gonna interfere with you packaging. But I will give a few suggestions:

It is valuable input to hear suggestions from the project owner, so thank you!

1. Consider packaging gstreamer plugin (gst-plugin-gtuber) seperately, this way apps that want to use only our extractor won't have to pull whole gstreamer with them. Currently there are none probably, but might be worth considering anyway.

Yes, I've split it into four packages:

libgtuber-0.0-0_0.0+git20221030.15f63bb-1_amd64.deb contains the shared libraries and only depends on libglib2.0-0, libjson-glib-1.0-0, libsoup-3.0-0 and libxml2

./usr/lib/x86_64-linux-gnu/gtuber-0.0/libgtuber-bilibili.so
./usr/lib/x86_64-linux-gnu/gtuber-0.0/libgtuber-crunchyroll-beta.so
./usr/lib/x86_64-linux-gnu/gtuber-0.0/libgtuber-invidious.so
./usr/lib/x86_64-linux-gnu/gtuber-0.0/libgtuber-lbry.so
./usr/lib/x86_64-linux-gnu/gtuber-0.0/libgtuber-niconico.so
./usr/lib/x86_64-linux-gnu/gtuber-0.0/libgtuber-peertube.so
./usr/lib/x86_64-linux-gnu/gtuber-0.0/libgtuber-piped.so
./usr/lib/x86_64-linux-gnu/gtuber-0.0/libgtuber-reddit.so
./usr/lib/x86_64-linux-gnu/gtuber-0.0/libgtuber-twitch.so
./usr/lib/x86_64-linux-gnu/gtuber-0.0/libgtuber-youtube.so
./usr/lib/x86_64-linux-gnu/libgtuber-0.0.so.0.4.0
./usr/lib/x86_64-linux-gnu/libgtuber-utils-common-0.0.so.0.4.0
./usr/lib/x86_64-linux-gnu/libgtuber-utils-json-0.0.so.0.4.0
./usr/lib/x86_64-linux-gnu/libgtuber-utils-xml-0.0.so.0.4.0
./usr/lib/x86_64-linux-gnu/libgtuber-utils-youtube-0.0.so.0.4.0

libgtuber-dev_0.0+git20221030.15f63bb-1_amd64.deb contains the development headers, pkgconfig file, examples, gir file and vala vapi files:

./usr/include/gtuber-0.0/gtuber/gtuber-adaptive-stream-devel.h
./usr/include/gtuber-0.0/gtuber/gtuber-adaptive-stream.h
./usr/include/gtuber-0.0/gtuber/gtuber-cache.h
./usr/include/gtuber-0.0/gtuber/gtuber-client.h
./usr/include/gtuber-0.0/gtuber/gtuber-config.h
./usr/include/gtuber-0.0/gtuber/gtuber-enums.h
./usr/include/gtuber-0.0/gtuber/gtuber-enum-types.h
./usr/include/gtuber-0.0/gtuber/gtuber.h
./usr/include/gtuber-0.0/gtuber/gtuber-heartbeat.h
./usr/include/gtuber-0.0/gtuber/gtuber-manifest-generator.h
./usr/include/gtuber-0.0/gtuber/gtuber-media-info-devel.h
./usr/include/gtuber-0.0/gtuber/gtuber-media-info.h
./usr/include/gtuber-0.0/gtuber/gtuber-misc-functions.h
./usr/include/gtuber-0.0/gtuber/gtuber-plugin-devel.h
./usr/include/gtuber-0.0/gtuber/gtuber-stream-devel.h
./usr/include/gtuber-0.0/gtuber/gtuber-stream.h
./usr/include/gtuber-0.0/gtuber/gtuber-types.h
./usr/include/gtuber-0.0/gtuber/gtuber-version.h
./usr/include/gtuber-0.0/gtuber/gtuber-website.h
./usr/lib/x86_64-linux-gnu/pkgconfig/gtuber-0.0.pc
./usr/share/doc/libgtuber-dev/examples/c/client.c
./usr/share/doc/libgtuber-dev/examples/gjs/client_async.js
./usr/share/doc/libgtuber-dev/examples/gjs/client.js
./usr/share/doc/libgtuber-dev/examples/python/client.py
./usr/share/doc/libgtuber-dev/examples/rust/Cargo.toml
./usr/share/doc/libgtuber-dev/examples/rust/src/main.rs
./usr/share/doc/libgtuber-dev/examples/vala/client.vala
./usr/share/gir-1.0/Gtuber-0.0.gir
./usr/share/vala/vapi/gtuber-0.0.deps
./usr/share/vala/vapi/gtuber-0.0.vapi
./usr/share/vala/vapi/gtuber-plugin-devel-0.0.deps
./usr/share/vala/vapi/gtuber-plugin-devel-0.0.vapi

gstreamer1.0-gtuber_0.0+git20221030.15f63bb-1_amd64.deb contains the gstreamer plugin and depends on libgtuber and libgstreamer:

./usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstgtuber.so

gir1.2-gtuber-0.0_0.0+git20221030.15f63bb-1_amd64.deb contains the GI typelib

./usr/lib/x86_64-linux-gnu/girepository-1.0/Gtuber-0.0.typelib
2. If you are working with some very low-end ARM hard disk space limited machine, it is possible to package plugins separately (even each in its own package), but this might be an overkill for both you and hard for explaining to people that they have to install them one by one from the ones they care about.

I've used to own those but that was more than 10 years ago. These days, even my router has several gigabytes of ram and even more flash storage. Do you know of any hardware that is still in production where disk space is enough of a problem to warrant the complexity?

3. I know that Debian likes testing stuff, but you shouldn't run plugins test on build. They won't run if `GITHUB_ACTIONS` env is present. Might be easier to set when building then patching stuff to disable them.

Yes, Debian loves tests but the Debian also disables any network connections except for loopback during package builds. As far as I can see the gtuber tests do access the internet, so those cannot be run during Debian package builds anyways.

As far as I see, all your other questions were answered here earlier. If you have something else to ask, feel free to drop and ask me directly on Clapper matrix channel (those 2 projects are somewhat related, so its also fine asking gtuber questions there too).

I am currently not using matrix for anything but if I have more quick questions I'll consider installing a matrix client and dropping by. :)

Thank you!

Rafostar commented 1 year ago

The packages seem like what I had in mind when making this. Thanks for your work.

I've used to own those but that was more than 10 years ago. These days, even my router has several gigabytes of ram and even more flash storage.

Huh, I though that was the main reason ARM users with limited flash storage want to have native packages instead of installing Flatpaks.

As far as I can see the gtuber tests do access the internet

Yea, right now we only have plugins tests. Adding unit testing for different internal functions is something I should do too, but I am planning to work on that part later (when API gets more stable).