/* * 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.streaming; import java.io.File; import java.io.FileFilter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import uk.co.caprica.vlcj.binding.internal.libvlc_media_t; import uk.co.caprica.vlcj.medialist.MediaList; import uk.co.caprica.vlcj.player.MediaPlayerFactory; import uk.co.caprica.vlcj.player.list.MediaListPlayer; import uk.co.caprica.vlcj.player.list.MediaListPlayerEventAdapter; import uk.co.caprica.vlcj.player.list.MediaListPlayerMode; import uk.co.caprica.vlcj.test.VlcjTest; /** * A simple example combining a media list player along with network streaming. * <p> * A directory is scanned recursively for mp3 files to create a play-list. This play-list is then * randomised before being played through a media list player. * <p> * Since a multicast streaming protocol is used, you can have any number of concurrent clients. You * can use any client you want, whether it is vlc itself, another client built using vlcj or any * other client that can receive and play audio over RTP. * <p> * You specify three arguments on the command-line when starting this application: * <ul> * <li>root directory to recursively scan for audio files</li> * <li>multicast address to stream to</li> * <li>port to stream to</li> * </ul> * For example: * * <pre> * /home/music 230.0.0.1 5555 * </pre> * * Using this example, the streaming audio can be played in vlc with the following address: * * <pre> * rtp://230.0.0.1:5555 * </pre> */ public class StreamingAudioPlayListTest extends VlcjTest { private final MediaPlayerFactory factory; private final MediaListPlayer mediaListPlayer; private final MediaList playList; public static void main(String[] args) throws Exception { if(args.length == 3) { String dir = args[0]; String address = args[1]; int port = Integer.parseInt(args[2]); new StreamingAudioPlayListTest().start(dir, address, port); } else { System.out.println("Specify <media root directory> <multicast address> <port>"); System.out.println("e.g. /home/music 230.0.0.1 5555"); } } public StreamingAudioPlayListTest() { factory = new MediaPlayerFactory(); mediaListPlayer = factory.newMediaListPlayer(); mediaListPlayer.addMediaListPlayerEventListener(new MediaListPlayerEventAdapter() { @Override public void nextItem(MediaListPlayer mediaListPlayer, libvlc_media_t item, String itemMrl) { System.out.println("Playing next item: " + itemMrl + " (" + item + ")"); } }); playList = factory.newMediaList(); } private void start(String dir, String address, int port) throws Exception { System.out.println("Scanning for audio files..."); // Scan for media files List<File> files = scanForMedia(dir); // Randomise the order Collections.shuffle(files); // Prepare the media options for streaming String mediaOptions = formatRtpStream(address, port); // Add each media file to the play-list... for(File file : files) { // You could instead set standard options on the media list player rather // than setting options each time you add media playList.addMedia(file.getAbsolutePath(), mediaOptions); } // Loop the play-list over and over mediaListPlayer.setMode(MediaListPlayerMode.LOOP); // Attach the play-list to the media list player mediaListPlayer.setMediaList(playList); // Finally, start the media player mediaListPlayer.play(); System.out.println("Streaming started at rtp://" + address + ":" + port); // Wait forever... Thread.currentThread().join(); } /** * Search a directory, recursively, for mp3 files. * * @param root root directory * @return collection of mp3 files */ private List<File> scanForMedia(String root) { List<File> result = new ArrayList<File>(400); scanForMedia(new File(root), result); return result; } private void scanForMedia(File root, List<File> result) { if(root.exists() && root.isDirectory()) { // List all matching mp3 files... File[] files = root.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isFile() && pathname.getName().toLowerCase().endsWith(".mp3"); } }); // Add them to the collection result.addAll(Arrays.asList(files)); // List all nested directories... File[] dirs = root.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isDirectory(); } }); // Recursively scan each nested directory... for(File dir : dirs) { scanForMedia(dir, result); } } } private String formatRtpStream(String serverAddress, int serverPort) { StringBuilder sb = new StringBuilder(60); sb.append(":sout=#rtp{dst="); sb.append(serverAddress); sb.append(",port="); sb.append(serverPort); sb.append(",mux=ts}"); return sb.toString(); } }