Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Digital Signage (MediaWSDemo) added

Support for avi, mp4 and m4v files
  • Loading branch information...
commit 8b802a89b968dddb320a467ee664ea30be9b73d9 1 parent b81c352
mgrundy authored
View
8 MediaWSDemo/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path=""/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="con" path="com.buglabs.dragonfly.jdt.BugClasspathContainerInitializer"/>
+ <classpathentry kind="output" path=""/>
+</classpath>
View
29 MediaWSDemo/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>MediaWSDemo</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.buglabs.dragonfly.BugApplicationNature</nature>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
View
7 MediaWSDemo/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+#Fri May 20 15:58:33 EDT 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.source=1.6
View
15 MediaWSDemo/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bug-Bundle-Type: Application
+Bundle-Vendor: vish
+Bundle-Version: 1.0.0
+BUG-API-Version: 2.0.2
+Bundle-Name: MediaWSDemo
+Bundle-Activator: mediawsdemo.Activator
+Bundle-ManifestVersion: 2
+Bundle-Description: Creates a MediaPlayer webservice to control select
+ ion of video being displayed out BUGview or BUGvideo
+Import-Package: com.buglabs.application,com.buglabs.bug.module.video.p
+ ub,com.buglabs.device,com.buglabs.services.ws,com.buglabs.util,org.os
+ gi.framework,org.osgi.service.log,org.osgi.util.tracker
+Bundle-SymbolicName: MediaWSDemo
+
View
52 MediaWSDemo/mediawsdemo/Activator.java
@@ -0,0 +1,52 @@
+/**
+ * Generated by Dragonfly SDK.
+ */
+package mediawsdemo;
+
+
+import com.buglabs.device.IButtonEventProvider;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.buglabs.application.ServiceTrackerHelper;
+import com.buglabs.bug.module.video.pub.IVideoModuleControl;
+
+
+/**
+ * BundleActivator for MediaWSDemo. The OSGi entry point to the application.
+ *
+ */
+public class Activator implements BundleActivator {
+ /**
+ * OSGi services the application depends on.
+ */
+ private static final String [] services = {
+ IButtonEventProvider.class.getName(),
+ IVideoModuleControl.class.getName(),
+ };
+ private ServiceTracker serviceTracker;
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ //Begin tracking services, and when all services are available, create thread and call ManagedRunnable.run().
+ serviceTracker = ServiceTrackerHelper.openServiceTracker(context, services, new MediaWSDemoApplication(context));
+
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+
+ //Will cause the ManagedRunnable.shutdown() to be called.
+ serviceTracker.close();
+ }
+
+
+}
View
295 MediaWSDemo/mediawsdemo/JMPlayer.java
@@ -0,0 +1,295 @@
+package mediawsdemo;
+
+import java.io.*;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+/**
+ * A player which is actually an interface to the famous MPlayer.
+ * @author Adrian BER
+ *
+ * revised by vish@buglabs.net to work with Bug2.0 Applications
+ */
+public class JMPlayer {
+
+ private static Logger logger = Logger.getLogger(JMPlayer.class.getName());
+
+ /** A thread that reads from an input stream and outputs to another line by line. */
+ private static class LineRedirecter extends Thread {
+ /** The input stream to read from. */
+ private InputStream in;
+ /** The output stream to write to. */
+ private OutputStream out;
+ /** The prefix used to prefix the lines when outputting to the logger. */
+ private String prefix;
+
+ /**
+ * @param in the input stream to read from.
+ * @param out the output stream to write to.
+ * @param prefix the prefix used to prefix the lines when outputting to the logger.
+ */
+ LineRedirecter(InputStream in, OutputStream out, String prefix) {
+ this.in = in;
+ this.out = out;
+ this.prefix = prefix;
+ }
+
+ public void run()
+ {
+ try {
+ // creates the decorating reader and writer
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ PrintStream printStream = new PrintStream(out);
+ String line;
+
+ // read line by line
+ while ( (line = reader.readLine()) != null) {
+ logger.info((prefix != null ? prefix : "") + line);
+ printStream.println(line);
+ }
+ } catch (IOException exc) {
+ logger.log(Level.WARNING, "An error has occured while grabbing lines", exc);
+ }
+ }
+
+ }
+
+ /** The path to the MPlayer executable. */
+ private String mplayerPath = "mplayer";
+ /** Options passed to MPlayer. */
+// private String mplayerOptions = " -slave -idle -vf screenshot";
+ private String mplayerOptions = "-fs -slave -idle -quiet -nocorrect-pts -fs -x 640 -y 480" ;
+
+ /** The process corresponding to MPlayer. */
+ private Process mplayerProcess;
+ /** The standard input for MPlayer where you can send commands. */
+ private PrintStream mplayerIn;
+ /** A combined reader for the the standard output and error of MPlayer. Used to read MPlayer responses. */
+ private BufferedReader mplayerOutErr;
+
+ public JMPlayer() {
+ }
+
+ /** @return the path to the MPlayer executable. */
+ public String getMPlayerPath() {
+ return mplayerPath;
+ }
+
+ public void open() throws IOException {
+ String path = " tv://" ;
+
+ if (mplayerProcess == null) {
+ // start MPlayer as an external process
+ String command = mplayerPath + mplayerOptions + path ;
+ logger.info("Starting MPlayer process: " + command);
+ mplayerProcess = Runtime.getRuntime().exec(command);
+
+ // create the piped streams where to redirect the standard output and error of MPlayer
+ // specify a bigger pipesize
+ PipedInputStream readFrom = new PipedInputStream(1024*1024);
+ PipedOutputStream writeTo = new PipedOutputStream(readFrom);
+ mplayerOutErr = new BufferedReader(new InputStreamReader(readFrom));
+
+ // create the threads to redirect the standard output and error of MPlayer
+ new LineRedirecter(mplayerProcess.getInputStream(), writeTo, "MPlayer says: ").start();
+ new LineRedirecter(mplayerProcess.getErrorStream(), writeTo, "MPlayer encountered an error: ").start();
+
+ // the standard input of MPlayer
+ mplayerIn = new PrintStream(mplayerProcess.getOutputStream());
+ } else {
+ execute("loadfile \"" + path + "\" 0");
+ }
+ // wait to start playing
+ waitForAnswer("Starting playback...");
+ logger.info("Started playing file " + path);
+ }
+ /** Sets the path to the MPlayer executable.
+ * @param mplayerPath the new MPlayer path; this will be actually efective
+ * after {@link #close() closing} the currently running player.
+ */
+ public void setMPlayerPath(String mplayerPath) {
+ this.mplayerPath = mplayerPath;
+ }
+
+
+ public void open(File file) throws IOException {
+ String path = file.getAbsolutePath().replace('\\', '/');
+ if (mplayerProcess == null) {
+ // start MPlayer as an external process
+ String command = "\"" + mplayerPath + "\" " + mplayerOptions + " \"" + path + "\"";
+ logger.info("Starting MPlayer process: " + command);
+ mplayerProcess = Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", command});
+
+ // create the piped streams where to redirect the standard output and error of MPlayer
+ // specify a bigger pipesize
+ PipedInputStream readFrom = new PipedInputStream(1024*1024);
+ PipedOutputStream writeTo = new PipedOutputStream(readFrom);
+ mplayerOutErr = new BufferedReader(new InputStreamReader(readFrom));
+
+ // create the threads to redirect the standard output and error of MPlayer
+ new LineRedirecter(mplayerProcess.getInputStream(), writeTo, "MPlayer says: ").start();
+ new LineRedirecter(mplayerProcess.getErrorStream(), writeTo, "MPlayer encountered an error: ").start();
+
+ // the standard input of MPlayer
+ mplayerIn = new PrintStream(mplayerProcess.getOutputStream());
+ } else {
+ execute("loadfile \"" + path + "\" 0");
+ }
+ // wait to start playing
+ waitForAnswer("Starting playback...");
+ logger.info("Started playing file " + path);
+ }
+
+ public void close() {
+ if (mplayerProcess != null) {
+ execute("quit");
+ try {
+ mplayerProcess.waitFor();
+ }
+ catch (InterruptedException e) {}
+ mplayerProcess = null;
+ }
+ }
+
+ public File getPlayingFile() {
+ String path = getProperty("path");
+ return path == null ? null : new File(path);
+ }
+
+ public void togglePlay() {
+ execute("pause");
+ }
+
+ public boolean isPlaying() {
+ return mplayerProcess != null;
+ }
+
+ public long getTimePosition() {
+ return getPropertyAsLong("time_pos");
+ }
+
+ public void setTimePosition(long seconds) {
+ setProperty("time_pos", seconds);
+ }
+
+ public long getTotalTime() {
+ return getPropertyAsLong("length");
+ }
+
+ public float getVolume() {
+ return getPropertyAsFloat("volume");
+ }
+
+ public void setVolume(float volume) {
+ setProperty("volume", volume);
+ }
+
+ public void doScreenShot() {
+ execute("screenshot 0");
+ }
+
+ protected String getProperty(String name) {
+ if (name == null || mplayerProcess == null) {
+ return null;
+ }
+ String s = "ANS_" + name + "=";
+ String x = execute("get_property " + name, s);
+ if (x == null)
+ return null;
+ if (!x.startsWith(s))
+ return null;
+ return x.substring(s.length());
+ }
+
+ protected long getPropertyAsLong(String name) {
+ try {
+ return Long.parseLong(getProperty(name));
+ }
+ catch (NumberFormatException exc) {}
+ catch (NullPointerException exc) {}
+ return 0;
+ }
+
+ protected float getPropertyAsFloat(String name) {
+ try {
+ return Float.parseFloat(getProperty(name));
+ }
+ catch (NumberFormatException exc) {}
+ catch (NullPointerException exc) {}
+ return 0f;
+ }
+
+ protected void setProperty(String name, String value) {
+ execute("set_property " + name + " " + value);
+ }
+
+ protected void setProperty(String name, long value) {
+ execute("set_property " + name + " " + value);
+ }
+
+ protected void setProperty(String name, float value) {
+ execute("set_property " + name + " " + value);
+ }
+
+ /** Sends a command to MPlayer..
+ * @param command the command to be sent
+ */
+ private void execute(String command) {
+ execute(command, null);
+ }
+
+ /** Sends a command to MPlayer and waits for an answer.
+ * @param command the command to be sent
+ * @param expected the string with which has to start the line; if null don't wait for an answer
+ * @return the MPlayer answer
+ */
+ private String execute(String command, String expected) {
+ if (mplayerProcess != null) {
+ logger.info("Send to MPlayer the command \"" + command + "\" and expecting "
+ + (expected != null ? "\"" + expected + "\"" : "no answer"));
+ mplayerIn.print(command);
+ mplayerIn.print("\n");
+ mplayerIn.flush();
+ logger.info("Command sent");
+ if (expected != null) {
+ String response = waitForAnswer(expected);
+ logger.info("MPlayer command response: " + response);
+ return response;
+ }
+ }
+ return null;
+ }
+
+ /** Read from the MPlayer standard output and error a line that starts with the given parameter and return it.
+ * @param expected the expected starting string for the line
+ * @return the entire line from the standard output or error of MPlayer
+ */
+ private String waitForAnswer(String expected) {
+ // todo add the possibility to specify more options to be specified
+ // todo use regexp matching instead of the beginning of a string
+ String line = null;
+ if (expected != null) {
+ try {
+ while ((line = mplayerOutErr.readLine()) != null) {
+ logger.info("Reading line: " + line);
+ if (line.startsWith(expected)) {
+ return line;
+ }
+ }
+ }
+ catch (IOException e) {
+ }
+ }
+ return line;
+ }
+//
+// public static void main(String[] args) throws IOException {
+// JMPlayer jmPlayer = new JMPlayer();
+// // open a video file
+// jmPlayer.open(new File("video.avi"));
+// // skip 2 minutes
+// jmPlayer.setTimePosition(120);
+// // set volume to 90%
+// jmPlayer.setVolume(90);
+// }
+}
View
226 MediaWSDemo/mediawsdemo/MediaWSDemoApplication.java
@@ -0,0 +1,226 @@
+package mediawsdemo;
+
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.ListSelectionModel;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import mediawsdemo.JMPlayer;
+
+import com.buglabs.application.IServiceProvider;
+import com.buglabs.application.MainApplicationThread;
+import com.buglabs.device.ButtonEvent;
+import com.buglabs.device.IButtonEventListener;
+import com.buglabs.device.IButtonEventProvider;
+import com.buglabs.services.ws.IWSResponse;
+import com.buglabs.services.ws.PublicWSDefinition;
+import com.buglabs.services.ws.PublicWSProvider2;
+import com.buglabs.services.ws.PublicWSProviderWithParams;
+import com.buglabs.services.ws.WSResponse;
+import com.buglabs.application.ServiceTrackerHelper.ManagedRunnable;
+import com.buglabs.bug.module.video.pub.IVideoModuleControl;
+/**
+ * This class represents the running application when all service dependencies are fulfilled.
+ *
+ * The run() method will be called with a map containing all the services specified in ServiceTrackerHelper.openServiceTracker().
+ * The application will run in a separate thread than the caller of start() in the Activator. See
+ * ManagedInlineRunnable for a thread-less application.
+ *
+ * By default, the application will only be started when all service dependencies are fulfilled. For
+ * finer grained service binding logic, see ServiceTrackerHelper.openServiceTracker(BundleContext context, String[] services, Filter filter, ServiceTrackerCustomizer customizer)
+ */
+public class MediaWSDemoApplication implements IButtonEventListener, ManagedRunnable, PublicWSProviderWithParams {
+
+ public IButtonEventProvider bep ;
+ public JMPlayer jmplayer = null;
+ private DefaultListModel listModel;
+ private File[] foundMedia;
+ private ServiceRegistration cameraControlWSReg;
+ private BundleContext theContext ;
+ private static final String mediaRoot = "/media/sda1" ;
+// private static final String mediaRoot = "/home/root/Media");
+
+ public MediaWSDemoApplication(BundleContext context) {
+ theContext = context ;
+ }
+
+ public void run(Map<Object, Object> services) {
+ IButtonEventProvider ibuttoneventprovider = (IButtonEventProvider) services.get(IButtonEventProvider.class.getName());
+ ibuttoneventprovider.addListener(this);
+ IVideoModuleControl ivideomodulecontrol = (IVideoModuleControl) services.get(IVideoModuleControl.class.getName());
+ ivideomodulecontrol.setDVI() ;
+
+ cameraControlWSReg = theContext.registerService(PublicWSProvider2.class.getName(), this, null);
+
+ try {
+ // initialize mplayer
+ Runtime.getRuntime()
+ .exec(new String[] { "/bin/sh", "-c",
+ "export DISPLAY=:0.0 &" });
+ this.jmplayer = new JMPlayer();
+
+ findMedia();
+ System.out.println("Found the following media files: ");
+ for (int i=0; i<foundMedia.length; i++) {
+ System.out.println(foundMedia[i]);
+ }
+ } catch (final IOException e) {
+ System.err.println("Failed to initiate mplayer: " + e);
+ }
+ }
+
+ public void findMedia() {
+ File root = new File(mediaRoot);
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ String lowercaseName = name.toLowerCase();
+ if (lowercaseName.endsWith(".avi")) {
+ return true;
+ }
+ else if (lowercaseName.endsWith(".mp4")) {
+ return true;
+ } else if (lowercaseName.endsWith(".m4v")) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ };
+
+ foundMedia = root.listFiles(filter);
+ }
+
+ public void shutdown() {
+ if(jmplayer.isPlaying()) jmplayer.togglePlay();
+ }
+
+
+ public void buttonEvent(ButtonEvent event) {
+ if ((event.getButton() == ButtonEvent.BUTTON_BUG20_USER) &&
+ (event.getAction() == ButtonEvent.KEY_UP)) {
+ System.out.println("Button pressed");
+ if (jmplayer.isPlaying()) {
+ jmplayer.togglePlay();
+ }
+ }
+ }
+
+ private String serviceName = "MediaPlayer";
+ public void setPublicName(String name) {
+ serviceName = name;
+ }
+
+ public PublicWSDefinition discover(int operation) {
+ if (operation == PublicWSProvider2.GET) {
+ return new PublicWSDefinition() {
+
+ public List getParameters() {
+ return null;
+ }
+
+ public String getReturnType() {
+ return "text/plain";
+ }
+ };
+ }
+
+ return null;
+ }
+
+ public IWSResponse execute(int operation, String input, Map get, Map post) {
+ if (operation == PublicWSProvider2.GET) {
+ Iterator entries = get.entrySet().iterator();
+ while (entries.hasNext()) {
+ Entry thisEntry = (Entry) entries.next();
+ Object key = thisEntry.getKey();
+ Object value = thisEntry.getValue();
+ System.out.println("key: "+key.toString()+" value: "+value.toString());
+ }
+ String v = (String) get.get("vid");
+ if (v != null) {
+ final int i = Integer.parseInt(v);
+ System.out.println("playing " + foundMedia[i].getName());
+ try {
+ jmplayer.open(foundMedia[i]);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return new WSResponse("Success! Loading "+ foundMedia[Integer.parseInt(v)].getName() + ". Media will play immediately", "text/plain") ;
+ }
+
+ return null ;
+
+ }
+
+
+ public String getPublicName() {
+ return serviceName;
+ }
+
+
+ public String getDescription() {
+
+// String defaultDesc = "To select a video, change the URL in your browser to " +
+// "http://bugIP/service/MediaPlayer?vid=# <br>" +
+// "and replace '#' with the numbers below:<br><br>" ;
+//
+// StringBuffer bfr = new StringBuffer(defaultDesc);
+
+// for (int i=0; i<foundMedia.length; i++) {
+// bfr.append((i) + ": " + foundMedia[i].getName() + "<br>");
+// }
+ findMedia();
+
+ String defaultDesc = "To play media on a display attached to BUGvideo, choose from the links below." +
+ "Media files are placed in:<br>" + mediaRoot +
+ "<br><br>User Button = Play/Pause<br>" ;
+
+
+ StringBuffer bfr = new StringBuffer(defaultDesc);
+
+ for (int i=0; i<foundMedia.length; i++) {
+
+ bfr.append("<a href=\"/service/MediaPlayer?vid=" + i + "\">" + (i) + ": " + foundMedia[i].getName() + "</a><br>");
+ }
+
+ bfr.append("<br>*Note: Playback will begin immediately. Video that is too large to render properly" +
+ " will result in choppy playback.<br>") ;
+
+
+ return bfr.toString() ;
+
+ }
+
+
+ public IWSResponse execute(int operation, String input) {
+ return null;
+ }
+
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.