/* * This file is part of VLCJ. * * VLCJ is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VLCJ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VLCJ. If not, see <http://www.gnu.org/licenses/>. * * Copyright 2009-2016 Caprica Software Limited. */ package uk.co.caprica.vlcj.test.youtube; import java.util.List; import javax.swing.JFrame; import javax.swing.SwingUtilities; import uk.co.caprica.vlcj.binding.internal.libvlc_media_t; import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent; import uk.co.caprica.vlcj.player.MediaPlayer; import uk.co.caprica.vlcj.test.VlcjTest; /** * This test demonstrates how to manually handle the playing of YouTube videos. * <p> * Ordinarily, vlcj will play YouTube videos automatically if you simply invoke * {@link MediaPlayer#setPlaySubItems(boolean)}. This will instruct the media player to * automatically play any sub-items that get created. * <p> * To play a YouTube video with vlc, vlc is given the http: "watch" URL - this is not itself a * streaming MRL, it is a web-page. This web-page is then scraped, by a LUA script inside of vlc, * to locate the actual streaming MRL. If the vlc LUA script finds the MRL, then a sub-item gets * created containing that MRL. * <p> * This sub-item MRL must then itself be played. * <p> * At this point, either the movie will start playing, or the vlc LUA script did not find the MRL, * so it falls back to a "secondary" API which attempts to scrape the streaming MRL in a different * way. The result of this secondary API is yet another sub-item, (i.e. sub-item of the sub-item of * the original media), and you play that. * <p> * That all sounds long-winded and complicated, but in essence, to manually handle YouTube videos, * you simply play your URL, and in the "finished" event handler you simply keep playing the first * sub-item until there are no more. * <p> * Note that the primary API is the preferred API - the vlc LUA script is out-of-sync with the * YouTube web-page format. Ideally the LUA script would be changed. The whole scheme is brittle * since the YouTube web-page format could change at any time and be incompatible with the vlc LUA * script. * <p> * The secondary API is invoked by the vlc LUA script as a last-resort. * <p> * <em>A future version of vlcj will likely support this automatically.</em> */ @SuppressWarnings("serial") public class FallbackYouTubePlayer extends VlcjTest { private final EmbeddedMediaPlayerComponent mediaPlayerComponent; private final JFrame frame; public static void main(String[] args) throws Exception { final String mrl = "http://www.youtube.com/watch?v=gOTyD6ZYcP0"; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new FallbackYouTubePlayer().start(mrl); } }); Thread.currentThread().join(); } public FallbackYouTubePlayer() { mediaPlayerComponent = new EmbeddedMediaPlayerComponent() { @Override public void mediaSubItemAdded(MediaPlayer mediaPlayer, libvlc_media_t subItem) { // Show the sub-item being added for purposes of the test... System.out.println("mediaSubItemAdded: " + mediaPlayerComponent.getMediaPlayer().mrl(subItem)); } @Override public void finished(MediaPlayer mediaPlayer) { System.out.println("finished"); // This is key... // // On receipt of a "finished" event, check if sub-items have been created... List<String> subItems = mediaPlayer.subItems(); System.out.println("subItems=" + subItems); // If sub-items were created... if(subItems != null && !subItems.isEmpty()) { // Pick the first sub-item, and play it... String subItemMrl = subItems.get(0); mediaPlayer.playMedia(subItemMrl); // What will happen next... // // 1. if the vlc lua script finds the streaming MRL via the normal i.e. // "primary" method, then this subitem MRL will be the streaming MRL; or // 2. if the vlc lua script does not find the streaming MRL via the primary // method, then the vlc lua script fallback method is tried to locate the // streaming MRL and the next time a "finished" event is received there will // be a new sub-item for the just played subitem, and that will be the // streaming MRL } else { // Your own application would not exit, but would instead probably set some // state flag or fire some sort of signal or whatever that the media actually // finished System.exit(0); } } @Override public void error(MediaPlayer mediaPlayer) { // For some reason, even if things work, you get an error... you have to ignore // this error - but that of course makes handling real errors tricky System.out.println("Error!!!"); } }; frame = new JFrame("vlcj YouTube fallback test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(100, 100, 1200, 800); frame.setContentPane(mediaPlayerComponent); frame.setVisible(true); } private void start(String mrl) { mediaPlayerComponent.getMediaPlayer().playMedia(mrl); } }