If you're using your C2 as a desktop computer, chances are you're also surfing the web on it. By now you might have noticed that in-browser video playback may not have the performance you would expect… You can get 720p Youtube playback in-browser but it's choppy, so 360p is the only acceptable resolution where playback is ok. Other sites simply complain that they can't play video, so that's annoying.
Accelerated video playback requires two things - accelerated video decoding - which is handled by aml-libs on C1/C2 and accelerated rendering - which should be handled by X11 drivers. Unfortunately, chrome does not support accelerated video decoding for aml-libs, so playback is done with CPU decoding, which is slow. The idea of this article is to (somehow) offload video playback to a process which can do it accelerated and away from the browser.
The best way to do it
Well, the best way to have accelerated Chrome video playback is to change Chrome's source code and add support for aml-libs. If you look into Chromium's documentation (https://www.chromium.org/developers/des ... ents/video) you can see that a custom-built ffmpeg is used for video decoding. This means that once some brave developer ports aml-libs support to ffmpeg, we might have Chromium builds that play accelerated videos on C1/C2. Work is being done with patches to ffmpeg by forum user @LongChair that should allow native playback in the end: http://forum.odroid.com/viewtopic.php?f=112&t=23521. Hopefully, by the time you're reading this article this approach is already working.
Figure 1. Render Process diagram
The convoluted way to do it
This approach is inspired by work done by a friend of mine on Firefox. It might not be directly applicable to Chromium due to changes in Chromium's plugin API (and its deprecation of NAPI). So, the story goes that my friend has a very old PC that he uses to browse the web. Unfortunately the PC could not keep up with playing back video content in the browser but it could do the job in an external player, so my friend (whom I'll call Silviu for his protection) decided to do something about it instead of throwing money at the problem. He used Firefox, the Greasemonkey plugin, wrote his own Firefox plugin and managed to offload playback to mpv, but integrated things to appear to happen inside the browser window. This is what I wanted to try to replicate on Odroids at first.
In terms of presentation, using a plugin allows you to create a new operating system window (without titlebar decorations) and position it on top of the HTML5 video object. The fun fact is that the window is embedded inside the webpage so it scrolls and gets hidden out of view when you scroll. MPV can use the --wid parameter to draw its output to an arbitrary window (this works in Windows and Linux alike and is a cool option). This makes the player look like it's native and unobtrusive. Also, the plugin allows you to create multiple instances of the player (for different tabs for instance).
Figure 2. Mpv plays to a Mousepad editor window
Unfortunately, the solution I've seen was tested only on Firefox and Windows, but with a bit of work might be ported to Chromium as well. I have to convince my friend to release his sources so that others can join in…
Figure 3. Firefox proof-of-concept with skinned mpv controls
The way we're going to do it
A relatively simple way to get accelerated playback from the browser is to pass the URL of the video to a player which has aml-libs support. Fortunately, following a long and very entertaining discussion on the forum http://forum.odroid.com/viewtopic.php?f=136&t=21948 we now have a standalone player for the C2 and also patches to ffmpeg and mpv that could lead to a more diverse player selection in the future. But for our needs we'll use c2play, a minimalistic player built especially for the C2 by forum user crashoverride (http://forum.odroid.com/viewtopic.php?f=136&t=23143).
The plan consists of the following:
* Create a chrome plugin to send the current URL (or the video element's URL) to a backend script
* The backend script calls youtube-dl to get the video URL and calls the player to play it
Fortunately Chrome has a native messaging API (https://developer.chrome.com/extensions/nativeMessaging) that lets you communicate with external processes (which it's kind enough to spawn for you), so this is what we'll do.
To install c2play you will need to consult the latest instructions from the support thread http://forum.odroid.com/viewtopic.php?f=136&t=23143, since development is progressing rapidly. But at the time of this writing you can install it with:
Code: Select all
$ git clone -b beta1 https://github.com/OtherCrashOverride/c2play.git $ sudo apt-get install libasound2-dev libavformat-dev libass-dev libx11-dev premake4 $ cd c2play $ premake4 gmake $ make c2play-x11 $ sudo cp c2play-x11 /usr/local/bin/c2play-x11
Code: Select all
$ sudo curl -L https://yt-dl.org/downloads/latest/youtube-dl -o /usr/local/bin/youtube-dl $ sudo chmod a+rx /usr/local/bin/youtube-dl
Finally, to install the Chrome plugin that ties all of these together follow these steps:
Code: Select all
$ git clone https://github.com/mad-ady/odroid.c2.video.helper.git $ cd odroid.c2.video.helper $ sudo apt-get install libjson-perl libconfig-simple-perl x11-xclip $ sudo perl -MCPAN -e 'install Clipboard::Xclip'
Figure 4. Plugin installation
Once it is installed continue to install the backend script:
Code: Select all
$ cd host $ bash install_host.sh
At this point you should see a new button that looks like a video player (better icons are welcome!) next to your address bar.
Figure 5. Push the button!
Now, when you navigate to a website that has a video embedded you can press this button and the tab's URL will be passed to the backend script. The backend script will run it through youtube-dl (this can take about 5-6 seconds) and will obtain the URL of the video. It will then call the preferred player with this URL and playback should start. Here's a video of the installation (and playback) process:
At the time of writing I only tested it with c2play-x11 and playback is full-screen. In order to control it consult the help page http://forum.odroid.com/viewtopic.php?f ... 43&p156050. Adding windowed playback support is on crashoverride's todo list (https://github.com/OtherCrashOverride/c2play/issues/6) and will probably become a reality in the future. Also LongChair's mpv port could be used for playback. For now I've tried with the stock mpv and playback is fine for SD content, but 720p lags. You can view a demo here: https://youtu.be/fJLv0cwPyfg
Figure 6. Playback in mpv (non-accelerated)
The backend script has a configuration file stored at ~/.odroid.c2.video.helper.conf and has an ini syntax. Here you can disable debugging (which is on by default), you can change the player and set custom parameters (such as quality) for various sites supported by youtube-dl. For instance, the default config file sets the youtube quality to 720p (-f 22) and disables playlist support. You can add new sections that must have a name that matches the URL's domain. Also, the section name must not contain the character dot (".") because it's not well supported by the configuration parser module. To view debugging information you can run:
Code: Select all
$ sudo journalctl -f
Figure 7. Configuration sample
Playing 1080p or 4k from youtube is a bit more problematic because for resolutions higher than 720p youtube splits video and audio in two distinct streams and their player merges them in the client. This doesn't happen on other sites, like Vimeo, for instance. Fortunately, crashoverride has a branch (dualstream) that tries to support this https://github.com/OtherCrashOverride/c2play/issues/12. Preliminary tests show that he is on the right track - I was able to play 4K video with his player, but playback stalled after some seconds. This will likely improve in the near future.
So, what should you expect to work and what isn't working? Sites supported by youtube-dl, such as Youtube (obviously), Vimeo, Facebook, IMDB, Engadget, DailyMotion, TED, Cracked, Apple Trailers, 9gag TV and a variety of adult sites should work. In order to play content you need to navigate to a page with a single video on it and click on the button next to the address bar. However, sites which require login to view the content will not work, nor will sites which require cookies to access the data. Sample tested content:
Code: Select all
IMDB: http://www.imdb.com/video/imdb/vi1000650265?ref_=tt_pv_vi_aiv_1 Engadget: https://www.engadget.com/video/57e9cc8476a6056f1ea2995d/ Dailymotion: http://www.dailymotion.com/video/x4var61_eye-popping-gopro-footage-from-the-divers-perspective-in-mostar_sport TED: http://www.ted.com/talks/sam_harris_can_we_build_ai_without_losing_control_over_it Cracked: http://www.cracked.com/video_20178_sex-games-giant-tea-sets-craziest-star-trek-episode.html Apple trailers: http://trailers.apple.com/trailers/sony_pictures/passengers/ 9gag.tv: http://9gag.com/tv/p/awapEM/spacex-interplanetary-transport-system?ref=tcl Facebook: https://www.facebook.com/SpaceX/videos/vb.353851465130/10158028115495131/?type=3&theater
Figure 8. Normal video object vs media-source
So, for sites that use a video element with a real URL as src the plugin will play the content with the external player on the first playback attempt. If you try to play the video again (without reloading the page) it will play normally, inside the page. This is a protection in case the external player can't handle the video format and you want to fall back to the browser. In this case you should just see a black window flash briefly on the screen while playback is attempted, otherwise it will play normally.
I have released two versions of the plugin. Version 1.1 supports only playback through youtube-dl through the use of the toolbar button. Version 1.2 adds direct playback experimental support, but may not always work or may be too annoying for videos which play automatically when you enter the page, so which plugin you use is up to your needs.
I'd like to hear your suggestions and feedback on the support thread:
And all this wouldn't have been possible without the hard work of crashoverride and LongChair - so send them a big thanks!