Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit

  • Loading branch information...
commit d26734ea0518f3574f14c76a47a17dc063ad5828 0 parents
@softboysxp authored
1  .gitignore
@@ -0,0 +1 @@
+*.DS_Store*
25 LICENSE
@@ -0,0 +1,25 @@
+Copyright 2010 softboysxp.com. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ of conditions and the following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those of the
+authors and should not be interpreted as representing official policies, either expressed
+or implied, of <copyright holder>.
32 README
@@ -0,0 +1,32 @@
+This is a plugin for PS3 Media Server to support AudioBox.fm, a cloud streaming service.
+
+You can view a demo here: http://www.youtube.com/watch?v=1NgmU-qVB-E
+
+IMPORTANT NOTICE
+----------------
+
+This plugin uses the official AudioBox.fm Java library (https://github.com/audiobox/AudioBox.fm-JavaLib), which is licensed under GPL.
+
+INSTALL (Binary)
+----------------
+
+Download the jar file (which includes all dependencies) from Download section, put it under plugins/ directory of PS3 Media Server (PMS).
+Note that only the latest beta/dev version of PMS supports "AdditionalFolderAtRoot" plugins.
+
+For Mac OS X users, you need to open the .app bundle, put the file there, AND add a line: "<string>$JAVAROOT/plugins/audiobox.jar</string>" right after the line: "<string>$JAVAROOT/PMS.jar</string>" in Info.plist. This is a limitation of OS X's Java stub launcher.
+
+On first launch, go to the Plugin System settings of PMS, click the "AudioBox.fm" button, enter your credentials, SAVE, and optionally restart PMS (as PMS only initialize plugin once during startup).
+
+COMPILING
+---------
+
+Just run "ant" (you may need to edit build.xml to point to the correct location of PMS.jar)
+
+Optionally, you could build a newer version of AudioBox.fm-JavaLib and put the jar into lib/ (Note that you should either build AudioBox.fm-JavaLib without HTTPS support, or configure your Java key store to accept the CA of api.audiobox.fm)
+
+KNOWN ISSUES
+------------
+
+The plugin passes raw stream to MPlayer for transcoding, for some reason some files hosted on AudioBox.fm won't play back after transcoding. (Probably a configuration issue in PMS's MPlayer encoder)
+
+Have fun!
36 build.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="AudioBox" default="build">
+ <!-- set to your pms path -->
+ <property name="pms" value="../ps3mediaserver" />
+ <property name="pms.jar" value="${pms}/pms.jar" />
+ <property name="plugins" value="${pms}/plugins/" />
+
+ <property name="audiobox.jar" value="audiobox.jar" />
+
+ <path id="lib.path.ref">
+ <fileset id="libs.ref" dir="lib" includes="*.jar" excludes="*source*.*"/>
+ </path>
+
+ <target name="clean">
+ <delete dir="classes" quiet="true" />
+ <delete file="${audiobox.jar}" quiet="true" />
+ </target>
+
+ <target name="build" depends="clean">
+ <mkdir dir="classes" />
+ <javac srcdir="src" destdir="classes" target="1.5" classpathref="lib.path.ref" debug="on" debuglevel="lines,vars,source">
+ <classpath>
+ <pathelement location="${pms.jar}"/>
+ </classpath>
+ </javac>
+
+ <jar basedir="classes" destfile="${audiobox.jar}" compress="off" duplicate="preserve">
+ <zipgroupfileset refid="libs.ref" />
+ <fileset file="plugin" />
+ </jar>
+ </target>
+
+ <target name="deploy" depends="build">
+ <copy file="${audiobox.jar}" todir="${plugins}" overwrite="true" />
+ </target>
+</project>
BIN  lib/apache-mime4j-0.6.1.jar
Binary file not shown
BIN  lib/audiobox.fm-core-2.0.jar
Binary file not shown
BIN  lib/httpclient-4.0.1.jar
Binary file not shown
BIN  lib/httpcore-4.1.jar
Binary file not shown
BIN  lib/httpmime-4.0.1.jar
Binary file not shown
BIN  lib/log4j-1.2.15.jar
Binary file not shown
BIN  lib/slf4j-api-1.6.1.jar
Binary file not shown
BIN  lib/slf4j-log4j12-1.6.1.jar
Binary file not shown
1  plugin
@@ -0,0 +1 @@
+com.softboysxp.pms.plugin.audiobox.AudioBoxPlugin
32 src/com/softboysxp/pms/plugin/audiobox/AudioBoxPlaylist.java
@@ -0,0 +1,32 @@
+package com.softboysxp.pms.plugin.audiobox;
+
+import net.pms.PMS;
+import net.pms.dlna.virtual.VirtualFolder;
+
+import fm.audiobox.core.api.ModelItem;
+import fm.audiobox.core.models.Track;
+
+public class AudioBoxPlaylist extends VirtualFolder {
+ private ModelItem playlist;
+
+ public AudioBoxPlaylist(ModelItem playlist) {
+ super(playlist.getName(), null);
+
+ this.playlist = playlist;
+ }
+
+ @Override
+ public void discoverChildren() {
+ if (playlist == null) {
+ return;
+ }
+
+ try {
+ for (Track track : playlist.getTracks().getCollection()) {
+ addChild(new AudioBoxTrack(track));
+ }
+ } catch (Exception ex) {
+ PMS.error("Error fetching tracks: ", ex);
+ }
+ }
+}
47 src/com/softboysxp/pms/plugin/audiobox/AudioBoxPlaylists.java
@@ -0,0 +1,47 @@
+package com.softboysxp.pms.plugin.audiobox;
+
+import net.pms.PMS;
+import net.pms.dlna.virtual.VirtualFolder;
+
+import fm.audiobox.core.api.ModelsCollection;
+import fm.audiobox.core.api.ModelItem;
+import fm.audiobox.core.models.User;
+
+public class AudioBoxPlaylists extends VirtualFolder {
+ private User user = null;
+ private String type = null;
+
+ public AudioBoxPlaylists(User user, String type) {
+ super(type, null);
+
+ this.user = user;
+ this.type = type;
+ }
+
+ @Override
+ public void discoverChildren() {
+ if (user == null) {
+ return;
+ }
+
+ try {
+ ModelsCollection playlists = null;
+
+ if ("Playlists".equalsIgnoreCase(type)) {
+ playlists = user.getPlaylists();
+ } else if ("Artists".equalsIgnoreCase(type)) {
+ playlists = user.getArtists();
+ } else if ("Albums".equalsIgnoreCase(type)) {
+ playlists = user.getAlbums();
+ } else if ("Genres" .equalsIgnoreCase(type)) {
+ playlists = user.getGenres();
+ }
+
+ for (Object playlist : playlists.getCollection()) {
+ addChild(new AudioBoxPlaylist((ModelItem) playlist));
+ }
+ } catch (Exception ex) {
+ PMS.error("Error fetching tracks: ", ex);
+ }
+ }
+}
80 src/com/softboysxp/pms/plugin/audiobox/AudioBoxPlugin.java
@@ -0,0 +1,80 @@
+package com.softboysxp.pms.plugin.audiobox;
+
+import net.pms.PMS;
+
+import net.pms.external.AdditionalFolderAtRoot;
+import net.pms.dlna.DLNAResource;
+
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+import javax.swing.JPasswordField;
+
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+
+import javax.swing.event.AncestorEvent;
+import javax.swing.event.AncestorListener;
+
+public class AudioBoxPlugin implements AdditionalFolderAtRoot {
+ private static final String EMAIL = "com.softboysxp.pms.plugin.audiobox.email";
+ private static final String PASSWORD = "com.softboysxp.pms.plugin.audiobox.password";
+
+ private AudioBoxUser user;
+
+ public AudioBoxPlugin() {
+ }
+
+ public JComponent config() {
+ JPanel configPane = new JPanel(new GridBagLayout());
+
+ final JTextField emailField = new JTextField(20);
+ final JPasswordField passwordField = new JPasswordField(20);
+
+ emailField.setFont(passwordField.getFont());
+
+ emailField.setText((String) PMS.getConfiguration().getCustomProperty(EMAIL));
+ passwordField.setText((String) PMS.getConfiguration().getCustomProperty(PASSWORD));
+
+ configPane.add(new JLabel("Email"), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ configPane.add(emailField, new GridBagConstraints(1, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ configPane.add(new JLabel("Password"), new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+ configPane.add(passwordField, new GridBagConstraints(1, 1, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+
+ configPane.addAncestorListener(new AncestorListener() {
+ public void ancestorAdded(AncestorEvent event) {}
+ public void ancestorMoved(AncestorEvent event) {}
+
+ public void ancestorRemoved(AncestorEvent event) {
+ PMS.getConfiguration().setCustomProperty(EMAIL, emailField.getText());
+ PMS.getConfiguration().setCustomProperty(PASSWORD, new String(passwordField.getPassword()));
+ try {
+ PMS.getConfiguration().save();
+ } catch (Exception ex) {
+ PMS.error("Error saving password: ", ex);
+ }
+ }
+ });
+
+ return configPane;
+ }
+
+ public String name() {
+ return "AudioBox.fm";
+ }
+
+ public void shutdown() {
+
+ }
+
+ public DLNAResource getChild() {
+ if (user == null) {
+ user = new AudioBoxUser((String) PMS.getConfiguration().getCustomProperty(EMAIL),
+ (String) PMS.getConfiguration().getCustomProperty(PASSWORD));
+ }
+
+ return user;
+ }
+}
103 src/com/softboysxp/pms/plugin/audiobox/AudioBoxTrack.java
@@ -0,0 +1,103 @@
+package com.softboysxp.pms.plugin.audiobox;
+
+import net.pms.PMS;
+
+import net.pms.formats.Format;
+
+import net.pms.configuration.RendererConfiguration;
+
+import net.pms.dlna.DLNAResource;
+import net.pms.dlna.DLNAMediaInfo;
+import net.pms.dlna.DLNAMediaAudio;
+
+import fm.audiobox.core.models.Track;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class AudioBoxTrack extends DLNAResource {
+ private Track track;
+
+ public AudioBoxTrack(Track track) {
+ super(Format.AUDIO);
+ this.track = track;
+
+ this.media=new DLNAMediaInfo();
+ DLNAMediaAudio audio=new DLNAMediaAudio();
+ audio.album = track.getAlbum().getName();
+ audio.artist = track.getArtist().getName();
+ audio.songname = track.getTitle();
+ audio.year = track.getYear();
+
+ // the audio will be transcoded, this is not the value of the real stream
+ audio.nrAudioChannels = 2;
+ audio.codecA = "LPCM";
+
+ media.audioCodes.add(audio);
+
+ media.duration = DLNAMediaInfo.getDurationString(track.getDurationInSeconds());
+
+ media.mediaparsed = true; // this flag must be set manually here
+
+ this.ext = PMS.get().getAssociatedExtension("http://");
+ checktype();
+ this.player = PMS.get().getPlayer(net.pms.encoders.MPlayerWebAudio.class, this.ext);
+ }
+
+ @Override
+ protected String getThumbnailURL() {
+ return track.getAlbum().getCovers().getMedium();
+ }
+
+ @Override
+ public String getThumbnailContentType() {
+ if (getThumbnailURL() != null && getThumbnailURL().endsWith(".png"))
+ return PNG_TYPEMIME;
+ else
+ return super.getThumbnailContentType();
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return null;
+ }
+
+ public String getName() {
+ return track.getTitle();
+ }
+
+ public boolean isFolder() {
+ return false;
+ }
+
+ public long length() {
+ // this value will actually be ignored, actual length will be calculated
+ return DLNAMediaInfo.TRANS_SIZE;
+ }
+
+ public long lastModified() {
+ return 0;
+ }
+
+ @Override
+ public void discoverChildren() {
+
+ }
+
+ @Override
+ public String getSystemName() {
+ String url = null;
+ try {
+ url = track.getStreamUrl(true);
+ } catch (Exception ex) {
+ PMS.error("Error getting stream url", ex);
+ }
+ return url;
+ }
+
+ @Override
+ public boolean isValid() {
+ checktype();
+ return true;
+ }
+
+}
38 src/com/softboysxp/pms/plugin/audiobox/AudioBoxUser.java
@@ -0,0 +1,38 @@
+package com.softboysxp.pms.plugin.audiobox;
+
+import net.pms.PMS;
+import net.pms.dlna.virtual.VirtualFolder;
+
+import fm.audiobox.core.models.AudioBoxClient;
+import fm.audiobox.core.models.User;
+
+public class AudioBoxUser extends VirtualFolder {
+ private AudioBoxClient client;
+ private User user = null;
+
+ public AudioBoxUser(String email, String password) {
+ super("AudioBox.fm", null);
+
+ client = new AudioBoxClient();
+ try {
+ user = client.login(email, password);
+ } catch (Exception ex) {
+ // todo: handle exception
+ PMS.error("Error logging in: ", ex);
+ user = null;
+ }
+
+ addSubFolders();
+ }
+
+ public void addSubFolders() {
+ if (user == null) {
+ return;
+ }
+
+ addChild(new AudioBoxPlaylists(user, "Playlists"));
+ addChild(new AudioBoxPlaylists(user, "Artists"));
+ addChild(new AudioBoxPlaylists(user, "Albums"));
+ addChild(new AudioBoxPlaylists(user, "Genres"));
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.