<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-717495008245544812</id><updated>2011-11-27T16:31:08.099-08:00</updated><category term='javafx webm vp8 linux'/><title type='text'>JavaFX Musings and other Dribbles</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://javafxplace.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/717495008245544812/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://javafxplace.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jim Clarke</name><uri>http://www.blogger.com/profile/08796376851359253438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-717495008245544812.post-4887241544734979485</id><published>2010-06-22T18:32:00.000-07:00</published><updated>2010-06-22T18:51:10.318-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javafx webm vp8 linux'/><title type='text'>JavaFX and WEBM on Linux</title><content type='html'>&lt;style&gt;&lt;!--@import url(http://alexgorbatchev.com/pub/sh/current/styles/shCore.css);@import url(http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css);--&gt;&lt;/style&gt;&lt;br /&gt;Google recently announced that it has open sourced the WEBM container and the VP8 video codec (&lt;a href="http://www.webmproject.org/"&gt;WebM Project&lt;/a&gt;). Not to be left behind, I wanted to explore what would it take to enable WEBM video within the JavaFX platform. But first, a word about the JavaFX Video/Audio architecture.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The JavaFX 1.3 Video/Audio architecture is made of 2 layers. On top, is a layer that presents a common interface to the rest of the JavaFX platform, and underneath is a platform specific layer. On Windows, the platform specific layer calls out to DirectShow, on Mac it calls out the CoreVideo, and on Linux and OpenSolaris it calls out to the GStreamer library. Because GStreamer is open source and it is easy to get the latest bits, I decided to look to GStreamer on Linux to see if I can make the WEBM media container work.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It so happens that when Google announced that WEBM and VP8 would be open sourced, Collabora Mutlimedia and Entropy Wave simultaneously announced that they were open sourcing their GStreamer work that supports WEBM. That announcement is &lt;a href="http://blogs.gnome.org/uraeus/2010/05/19/webm-and-gstreamer/"&gt;here&lt;/a&gt;. Since then, this work has been incorporated in the main source repositories at &lt;a href="http://gstreamer.freedesktop.org/"&gt;GStreamer&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To start with, I am using the latest version of Ubuntu, 10.04 LTU, with kernel version 2.6.32-22.  For GStreamer, I downloaded the latest stable builds that include the WEBM support. Specifically,&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;gstreamer-0.10.29&lt;/li&gt;&lt;li&gt;gst-plugins-base-0.10.29&lt;/li&gt;&lt;li&gt;gst-plugins-good.0.10.23&lt;/li&gt;&lt;li&gt;gst-plugins-bad-0.10.19&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;I started with building the gstreamer core engine. First, from the initial install of Ubuntu, I had to install a few ubuntu packages required to build the gstreamer libraries.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;g++-4.4&lt;/li&gt;&lt;li&gt;libglib2.0-dev&lt;/li&gt;&lt;li&gt;liboil0.3-dev&lt;/li&gt;&lt;li&gt;build-essential&lt;/li&gt;&lt;li&gt;bison&lt;/li&gt;&lt;li&gt;flex&lt;/li&gt;&lt;li&gt;yasm&lt;/li&gt;&lt;li&gt;libvorbis-dev&lt;/li&gt;&lt;li&gt;libtheora-dev&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Then I went into the gstreamer-0.10.29 directory, and did the following:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;./configure&lt;/li&gt;&lt;li&gt;make&lt;/li&gt;&lt;li&gt;sudo make install&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;This made the basic gstreamer package, libraries and executables and installed them in /usr/local/.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I then repeated the steps for the gstreamer plugins contained in the gst-plugins-base-0.10.29, gst-plugins-good.0.10.23, and gst-plugins-bad-0.10.19 directories. (For an explanation of good, bad, and yes ugly, check out this &lt;a href="http://gstreamer.freedesktop.org/releases/gst-plugins-good/0.10.23.html"&gt;link&lt;/a&gt; at GStreamer.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I then installed the latest Java JDK for Linux from &lt;a href="http://java.sun.com/"&gt;http://java.sun.com&lt;/a&gt; and the latest JavaFX SDK for Linux from the &lt;a href="http://javafx.com/"&gt;JavaFX&lt;/a&gt; site.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next, I needed a WEBM video to test. Luckily, Google has started to convert the YouTube videos to WEBM, and this &lt;a href="http://googlesystem.blogspot.com/2010/05/how-to-play-webm-video-on-youtube.html"&gt;blog&lt;/a&gt; explains how to gain access to these videos. Because, YouTube WEBM support is still "experimental", you have to log into Google and opt-in to get access to the videos. To actually get to the video stream for use in JavaFX, I had to download the video directly to disk, because the video URL would not work outside of the browser from which I had logged into Google. When you do the search for the WEBM videos, not all of the returned listings are converted to WEBM yet. To find one that has been converted, select the listed item and if it is a WEBM video, "HTML5" will initially appear in the middle of the screen. To get to the actual video bits, I opened up the HTML source and looked for "webm", until I found the likely URL candidate. I then used that URL in the browser, and the bits were saved to the local disk in a file I named "videoplaypack.webm"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To play this in JavaFX, I wrote a simple application utilizing the JavaFX standard media classes.&lt;/div&gt;&lt;pre class="brush: jfx"&gt;package webmmovie;&lt;br /&gt;&lt;br /&gt;import javafx.stage.Stage;&lt;br /&gt;import javafx.scene.Scene;&lt;br /&gt;import javafx.scene.media.MediaView;&lt;br /&gt;import javafx.scene.media.MediaPlayer;&lt;br /&gt;import javafx.scene.media.Media;&lt;br /&gt;import javafx.scene.control.Button;&lt;br /&gt;import java.io.File;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * @author jclarke&lt;br /&gt; */&lt;br /&gt;var file = new File("/media/NONAME/videoplayback.webm");&lt;br /&gt;var scene: Scene;&lt;br /&gt;&lt;br /&gt;def player = MediaPlayer {&lt;br /&gt;    media: Media {&lt;br /&gt;        source: file.toURI().toString();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Stage {&lt;br /&gt;    title: "Application title"&lt;br /&gt;    scene: scene = Scene {&lt;br /&gt;        width: 500&lt;br /&gt;        height: 500&lt;br /&gt;        content: [&lt;br /&gt;            MediaView {&lt;br /&gt;                fitHeight: bind scene.height&lt;br /&gt;                fitWidth: bind scene.width&lt;br /&gt;                preserveRatio: true&lt;br /&gt;                mediaPlayer: player&lt;br /&gt;            }&lt;br /&gt;            Button {&lt;br /&gt;                text: "Play"&lt;br /&gt;                action: function () {&lt;br /&gt;                    player.stop();&lt;br /&gt;                    player.play();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        ]&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;However, when I went to run this, GStreamer presented me with an error stating it did not know how to handle the media type, "&lt;b&gt;video/x-vp8&lt;/b&gt;".  Running "gst-inspect" showed no such mapping to the &lt;i&gt;vp8&lt;/i&gt; plugin, though the &lt;i&gt;vp8&lt;/i&gt; plugin was listed. To rectify this, I had to  modify the &lt;i&gt;vp8&lt;/i&gt; plugin source to register a "&lt;i&gt;type_find&lt;/i&gt;" object that mapped the "&lt;b&gt;video/x-vp8&lt;/b&gt;" mime type to the &lt;i&gt;vp8&lt;/i&gt; plugin. The code I modified was in "gst-pugins-bad-0.10.19/ext/vp8/plugin.c" and is shown in the following listing. &lt;/div&gt;&lt;pre class="brush: c"&gt;#ifdef HAVE_CONFIG_H&lt;br /&gt;#include "config.h"&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#include &lt;gst/gst.h&gt;&lt;br /&gt;&lt;br /&gt;/*** video/x-vp8 typefinder (temporary) ***/&lt;br /&gt;static GstStaticCaps vp8_caps = GST_STATIC_CAPS ("video/x-vp8");&lt;br /&gt;&lt;br /&gt;#define VP8_CAPS (gst_static_caps_get(&amp;amp;vp8_caps))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;GType gst_vp8_dec_get_type (void);&lt;br /&gt;GType gst_vp8_enc_get_type (void);&lt;br /&gt;static void gst_vp8_typefind(GstTypeFind * tf, gpointer ignore);&lt;br /&gt;&lt;br /&gt;static gboolean&lt;br /&gt;plugin_init (GstPlugin * plugin)&lt;br /&gt;{&lt;br /&gt;#ifdef HAVE_VP8_DECODER&lt;br /&gt;  gst_element_register (plugin, "vp8dec", GST_RANK_PRIMARY,&lt;br /&gt;      gst_vp8_dec_get_type ());&lt;br /&gt;  gst_type_find_register(plugin, "video/x-vp8", GST_RANK_PRIMARY,&lt;br /&gt;      gst_vp8_typefind, NULL, VP8_CAPS, NULL, NULL);&lt;br /&gt;      &lt;br /&gt;      &lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#ifdef HAVE_VP8_ENCODER&lt;br /&gt;  gst_element_register (plugin, "vp8enc", GST_RANK_PRIMARY,&lt;br /&gt;      gst_vp8_enc_get_type ());&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;  return TRUE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#ifdef HAVE_VP8_ENCODER&lt;br /&gt;static void&lt;br /&gt;gst_vp8_typefind(GstTypeFind * tf, gpointer ignore) {&lt;br /&gt;    /* Magic number (DKIF) + version, + length + codec-FourCC */&lt;br /&gt;    guint8 *data = gst_type_find_peek (tf, 0, 12);&lt;br /&gt;    if(!data) return;&lt;br /&gt;&lt;br /&gt;    if(data[0] !='D' || data[1] !='K' || data[2] != 'I' || data[3] != 'F')&lt;br /&gt;         return;&lt;br /&gt;    &lt;br /&gt;    // TODO Check FourCC?&lt;br /&gt;    gst_type_find_suggest(tf, GST_TYPE_FIND_MAXIMUM, VP8_CAPS);&lt;br /&gt;}&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,&lt;br /&gt;    GST_VERSION_MINOR,&lt;br /&gt;    "vp8",&lt;br /&gt;    "VP8 plugin",&lt;br /&gt;    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)&lt;br /&gt;&lt;br /&gt;&lt;/gst/gst.h&gt;&lt;/pre&gt;&lt;div&gt;Once I remade and installed the gstreamer plugins, I re-ran my JavaFX application and all is good in the world again. The following is a screen image of the trailer for Avatar, found at this &lt;a href="http://www.youtube.com/watch?v=d1_JBMrrYw8"&gt;&lt;span class="Apple-style-span"&gt;link&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span"&gt; (assuming you have signed up for the WEBM experimental access).&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: black; font-family: Georgia, serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: black; font-family: Georgia, serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; color: #0000ee;"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5485745583469882722" src="http://2.bp.blogspot.com/_PPIkb9D-ovs/TCFIix7j7WI/AAAAAAAAAAM/qC7JaBqmTrk/s400/WEBM.jpg" style="cursor: pointer; display: block; height: 260px; margin-bottom: 10px; margin-left: auto; margin-right: auto; margin-top: 0px; text-align: center; width: 400px;" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: black; font-family: Georgia, serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline; color: #0000ee;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif;"&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: underline;"&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;CAVEAT&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span"&gt;: This is using internal behavior of the JavaFX runtime and there is no guarantee that future versions of JavaFX will work in this way.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif;"&gt;&lt;span class="Apple-style-span"&gt;With JavaFX 1.3, &amp;nbsp;it should be possible to add WEBM codecs to Windows DirectShow and JavaFX should then be able to play WEBM movies. However, I have not personally tried this. The WEBM project does provide a set of DirectShow Filters, found &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif;"&gt;&lt;a href="http://www.webmproject.org/tools/#directshow_filters"&gt;&lt;span class="Apple-style-span"&gt;here&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif;"&gt;&lt;span class="Apple-style-span"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/717495008245544812-4887241544734979485?l=javafxplace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javafxplace.blogspot.com/feeds/4887241544734979485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://javafxplace.blogspot.com/2010/06/javafx-and-webm-on-linux.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/717495008245544812/posts/default/4887241544734979485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/717495008245544812/posts/default/4887241544734979485'/><link rel='alternate' type='text/html' href='http://javafxplace.blogspot.com/2010/06/javafx-and-webm-on-linux.html' title='JavaFX and WEBM on Linux'/><author><name>Jim Clarke</name><uri>http://www.blogger.com/profile/08796376851359253438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_PPIkb9D-ovs/TCFIix7j7WI/AAAAAAAAAAM/qC7JaBqmTrk/s72-c/WEBM.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-717495008245544812.post-6128839407106396403</id><published>2010-05-29T04:12:00.000-07:00</published><updated>2010-05-29T04:19:07.334-07:00</updated><title type='text'>Introduction.</title><content type='html'>This is a continuation of my blog that I had started under Sun Microsystems, &lt;a href="http://blogs.sun.com/clarkeman/"&gt;http://blogs.sun.com/clarkeman/&lt;/a&gt;, to talk about various JavaFX topics.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lately, I have been digging deep into JavaFX 1.3 and will start posting again,&lt;/div&gt;&lt;div&gt;so stay tuned.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/717495008245544812-6128839407106396403?l=javafxplace.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javafxplace.blogspot.com/feeds/6128839407106396403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://javafxplace.blogspot.com/2010/05/introduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/717495008245544812/posts/default/6128839407106396403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/717495008245544812/posts/default/6128839407106396403'/><link rel='alternate' type='text/html' href='http://javafxplace.blogspot.com/2010/05/introduction.html' title='Introduction.'/><author><name>Jim Clarke</name><uri>http://www.blogger.com/profile/08796376851359253438</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
