Switched to Cling UPNP 2.0 Snapshot

git-svn-id: svn://svn.jdownloader.org/jdownloader/trunk@18164 ebf7c1c2-ba36-0410-9fe8-c592906822b4
This commit is contained in:
coalado 2012-08-03 10:15:22 +00:00
parent 8661e85393
commit 08918e0c18
34 changed files with 717 additions and 349 deletions

View File

@ -93,16 +93,30 @@
<classpathentry kind="lib" path="ressourcen/libs/bcprov-jdk15on-147.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sevenzipjbindingLinux.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sevenzipjbindingMac.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/cling-core-1.0.5.jar" sourcepath="C:/Users/Thomas/Downloads/cling-distribution-1.0.5/core/cling-core-1.0.5-sources.jar">
<classpathentry kind="lib" path="ressourcen/libs/UPNP/cling-core-2.0-SNAPSHOT.jar" sourcepath="C:/Users/Thomas/Downloads/cling-distribution-2.0-SNAPSHOT/core/src/main/java">
<attributes>
<attribute name="javadoc_location" value="http://4thline.org/projects/cling/core/apidocs/"/>
<attribute name="javadoc_location" value="file:/C:/Users/Thomas/Downloads/cling-distribution-2.0-SNAPSHOT/core/apidocs/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/cling-support-1.0.5.jar" sourcepath="C:/Users/Thomas/Downloads/cling-distribution-1.0.5/support/cling-support-1.0.5-sources.jar">
<classpathentry kind="lib" path="ressourcen/libs/UPNP/cling-support-2.0-SNAPSHOT.jar" sourcepath="C:/Users/Thomas/Downloads/cling-distribution-2.0-SNAPSHOT/support/src/main/java">
<attributes>
<attribute name="javadoc_location" value="http://4thline.org/projects/cling/support/apidocs/"/>
<attribute name="javadoc_location" value="file:/C:/Users/Thomas/Downloads/cling-distribution-2.0-SNAPSHOT/support/apidocs/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/seamless-http-1.0-SNAPSHOT.jar" sourcepath="C:/Users/Thomas/Downloads/cling-distribution-2.0-SNAPSHOT/core/src/main/java">
<attributes>
<attribute name="javadoc_location" value="file:/C:/Users/Thomas/Downloads/cling-distribution-2.0-SNAPSHOT/core/apidocs/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/seamless-util-1.0-20111017.170503-1.jar" sourcepath="C:/Users/Thomas/Downloads/cling-distribution-2.0-SNAPSHOT/core/src/main/java">
<attributes>
<attribute name="javadoc_location" value="file:/C:/Users/Thomas/Downloads/cling-distribution-2.0-SNAPSHOT/core/apidocs/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/seamless-xml-1.0-SNAPSHOT.jar" sourcepath="C:/Users/Thomas/Downloads/cling-distribution-2.0-SNAPSHOT/core/src/main/java">
<attributes>
<attribute name="javadoc_location" value="file:/C:/Users/Thomas/Downloads/cling-distribution-2.0-SNAPSHOT/core/apidocs/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/teleal-common-1.0.13.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -11,6 +11,7 @@ import org.appwork.net.protocol.http.HTTPConstants.ResponseCode;
import org.appwork.remoteapi.RemoteAPIException;
import org.appwork.remoteapi.RemoteAPIRequest;
import org.appwork.remoteapi.RemoteAPIResponse;
import org.appwork.utils.Files;
import org.appwork.utils.net.HTTPHeader;
import org.appwork.utils.net.Input2OutputStreamForwarder;
import org.appwork.utils.net.httpserver.requests.HttpRequest;
@ -68,14 +69,15 @@ public class VLCStreamingAPIImpl implements VLCStreamingAPI {
public static final int DLNA_ORG_FLAG_DLNA_V15 = (1 << 20);
@Override
public void video(RemoteAPIRequest request, RemoteAPIResponse response, String format) {
public void video(RemoteAPIRequest request, RemoteAPIResponse response, String path) {
try {
File fileToServe = new File(path);
System.out.println(path);
String format = Files.getExtension(fileToServe.getName());
// seeking
String dlnaFeatures = "DLNA.ORG_PN=" + format + ";DLNA.ORG_OP=" + DLNAOp.create(DLNAOp.RANGE_SEEK_SUPPORTED) + ";DLNA.ORG_FLAGS=" + DLNAOrg.create(DLNAOrg.STREAMING_TRANSFER_MODE);
File fileToServe = new File("g:\\test." + format);
String ct = "video/" + format;
if (format.equals("mp3")) {
ct = "audio/mpeg";

View File

@ -36,6 +36,7 @@ import org.jdownloader.extensions.extraction.Archive;
import org.jdownloader.extensions.extraction.ExtractionExtension;
import org.jdownloader.extensions.extraction.ValidateArchiveAction;
import org.jdownloader.extensions.vlcstreaming.gui.VLCGui;
import org.jdownloader.extensions.vlcstreaming.upnp.MediaServer;
import org.jdownloader.gui.menu.MenuContext;
import org.jdownloader.gui.menu.eventsender.MenuFactoryEventSender;
import org.jdownloader.gui.menu.eventsender.MenuFactoryListener;
@ -56,11 +57,14 @@ public class VLCStreamingExtension extends AbstractExtension<VLCStreamingConfig,
private String vlcBinary = null;
private VLCStreamingConfigPanel configPanel = null;
protected VLCGui tab;
private MediaServer mediaServer;
@Override
protected void stop() throws StopException {
try {
streamProvider = null;
if (mediaServer != null) mediaServer.shutdown();
MenuFactoryEventSender.getInstance().removeListener(this);
if (vlcstreamingAPI != null) {
RemoteAPIController.getInstance().unregister(vlcstreamingAPI);
@ -82,6 +86,8 @@ public class VLCStreamingExtension extends AbstractExtension<VLCStreamingConfig,
}
streamProvider = new VLCStreamingProvider(this);
vlcstreamingAPI = new VLCStreamingAPIImpl(this);
startMediaServer();
RemoteAPIController.getInstance().register(vlcstreamingAPI);
MenuFactoryEventSender.getInstance().addListener(this, true);
new EDTRunner() {
@ -93,6 +99,13 @@ public class VLCStreamingExtension extends AbstractExtension<VLCStreamingConfig,
}.waitForEDT();
}
private void startMediaServer() {
Thread serverThread = new Thread(mediaServer = new MediaServer());
serverThread.setDaemon(false);
serverThread.start();
}
public VLCStreamingAPIImpl getVlcstreamingAPI() {
return vlcstreamingAPI;
}

View File

@ -105,55 +105,58 @@ public class RarStreamer implements Runnable, StreamingInterface {
exec.start();
}
public void openArchive(Archive archive, ExtractionExtension extractor) throws ExtractionException, DialogClosedException, DialogCanceledException, InterruptedException {
open();
if (archive.isProtected()) {
HashSet<String> spwList = archive.getSettings().getPasswords();
HashSet<String> passwordList = new HashSet<String>();
if (spwList != null) {
passwordList.addAll(spwList);
}
passwordList.addAll(archive.getFactory().getGuessedPasswordList(archive));
passwordList.add(archive.getName());
ArrayList<String> pwList = extractor.getSettings().getPasswordList();
if (pwList == null) pwList = new ArrayList<String>();
passwordList.addAll(pwList);
logger.info("Start password finding for " + archive);
String correctPW = null;
for (String password : passwordList) {
if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
if (checkPassword(password)) {
correctPW = password;
break;
}
}
if (correctPW == null) {
String password = askPassword();
while (true) {
if (checkPassword(password)) {
break;
} else {
Dialog.getInstance().showMessageDialog(T._.wrong_password());
}
}
}
logger.info("Found password for " + archive + "->" + archive.getPassword());
/* avoid duplicates */
pwList.remove(archive.getPassword());
pwList.add(0, archive.getPassword());
extractor.getSettings().setPasswordList(pwList);
}
}
protected void openArchiveInDialog() throws DialogClosedException, DialogCanceledException, ExtractionException {
ProgressGetter pg = new ProgressDialog.ProgressGetter() {
@Override
public void run() throws Exception {
open();
if (archive.isProtected()) {
HashSet<String> spwList = archive.getSettings().getPasswords();
HashSet<String> passwordList = new HashSet<String>();
if (spwList != null) {
passwordList.addAll(spwList);
}
passwordList.addAll(archive.getFactory().getGuessedPasswordList(archive));
passwordList.add(archive.getName());
ArrayList<String> pwList = extractor.getSettings().getPasswordList();
if (pwList == null) pwList = new ArrayList<String>();
passwordList.addAll(pwList);
logger.info("Start password finding for " + archive);
String correctPW = null;
for (String password : passwordList) {
if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
if (checkPassword(password)) {
correctPW = password;
break;
}
}
if (correctPW == null) {
String password = askPassword();
while (true) {
if (checkPassword(password)) {
break;
} else {
Dialog.getInstance().showMessageDialog(T._.wrong_password());
}
}
}
logger.info("Found password for " + archive + "->" + archive.getPassword());
/* avoid duplicates */
pwList.remove(archive.getPassword());
pwList.add(0, archive.getPassword());
extractor.getSettings().setPasswordList(pwList);
}
openArchive(archive, extractor);
}

View File

@ -1,174 +0,0 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
import java.util.HashMap;
import org.appwork.exceptions.WTFException;
import org.teleal.cling.support.model.PersonWithRole;
import org.teleal.cling.support.model.Res;
import org.teleal.cling.support.model.item.Item;
import org.teleal.cling.support.model.item.MusicTrack;
import org.teleal.common.util.MimeType;
public class BasicContentProvider implements ContentProvider {
private RootContainer root;
public BasicContentProvider() {
createRoot();
FolderContainer downloadlist;
addChildren(root, downloadlist = new FolderContainer(1, "DownloadList"));
addChildren(downloadlist, new ContentItem(10) {
@Override
public Item getImpl() {
PersonWithRole artist = new PersonWithRole("MyArtist", "Performer");
MimeType mimeType = new MimeType("audio", "mpeg");
Res res = new Res(mimeType, 123456l, "00:03:25", 8192l, "http://192.168.2.122:3128/vlcstreaming/video?mp3");
return new MusicTrack(getID() + "", parent.getID() + "", "MyTitle.mp3", artist.getName(), "MyAlbum", artist, res);
}
});
addChildren(downloadlist, new ContentItem(11) {
@Override
public Item getImpl() {
PersonWithRole artist = new PersonWithRole("MyArtist", "Performer");
MimeType mimeType = new MimeType("audio", "mpeg");
Res res = new Res(mimeType, 123456l, "00:03:25", 8192l, "http://192.168.2.122:3128/vlcstreaming/video?mp3");
return new MusicTrack(getID() + "", parent.getID() + "", "MyTitle2.mp3", artist.getName(), "MyAlbum", artist, res);
}
});
// if (node instanceof ContainerNode) {
//
// // Container audio = new Container();
// // audio.setId("0");
// // audio.setParentID("-1");
// // audio.setTitle("Wurzel");
// // // audio.setCreator("JDownloader");
// // audio.setRestricted(true);
// // audio.setSearchable(false);
// //
// // audio.setChildCount(2);
// // audio.setClazz(new org.teleal.cling.support.model.DIDLObject.Class("object.container"));
//
// } else if (node instanceof ItemNode) {
// didl.addContainer(((ItemNode) node).getImpl());
// String didlStrng = new DIDLParser().generate(didl);
// didlStrng = didlStrng.replace("\"true\"", "\"1\"").replace("\"false\"", "\"0\"");
// System.out.println("-->" + didlStrng);
// return new BrowseResult(didlStrng, 1, 1);
// Container audio = new Container();
// audio.setId(ID_DOWNLOADLIST);
// audio.setParentID("0");
// audio.setTitle("DownloadList");
// audio.setCreator("JDownloader");
// audio.setRestricted(true);
// audio.setSearchable(true);
// audio.setWriteStatus(WriteStatus.NOT_WRITABLE);
// audio.setChildCount(3);
// audio.setClazz(new org.teleal.cling.support.model.DIDLObject.Class("object.container"));
// didl.addContainer(audio);
// String didlStrng = new DIDLParser().generate(didl);
// System.out.println("-->" + didlStrng);
//
// } else if (objectID.equals(ID_LINKGRABBER)) {
// Container movie = new Container();
// movie.setId(ID_LINKGRABBER);
// movie.setParentID("0");
// movie.setTitle("Linkgrabber");
// movie.setCreator("JDownloader");
// movie.setRestricted(true);
// movie.setSearchable(true);
// movie.setWriteStatus(WriteStatus.NOT_WRITABLE);
// movie.setChildCount(0);
// movie.setClazz(new org.teleal.cling.support.model.DIDLObject.Class("object.container"));
// didl.addContainer(movie);
// String didlStrng = new DIDLParser().generate(didl);
// System.out.println("-->" + didlStrng);
// return new BrowseResult(didlStrng, 0, 0);
// }
// } else {
//
// if (objectID.equals(ID_ROOT)) {
// // root
//
// Container audio = new Container();
// audio.setId(ID_DOWNLOADLIST);
// audio.setParentID("0");
// audio.setTitle("DownloadList");
// audio.setCreator("JDownloader");
// audio.setRestricted(true);
// audio.setSearchable(true);
// audio.setWriteStatus(WriteStatus.NOT_WRITABLE);
// audio.setChildCount(3);
// audio.setClazz(new org.teleal.cling.support.model.DIDLObject.Class("object.container"));
// didl.addContainer(audio);
//
// Container movie = new Container();
// movie.setId(ID_LINKGRABBER);
// movie.setParentID("0");
// movie.setTitle("Linkgrabber");
// movie.setCreator("JDownloader");
// movie.setRestricted(true);
// movie.setSearchable(true);
// movie.setWriteStatus(WriteStatus.NOT_WRITABLE);
// movie.setChildCount(0);
// movie.setClazz(new org.teleal.cling.support.model.DIDLObject.Class("object.container"));
// didl.addContainer(movie);
//
// String didlStrng = new DIDLParser().generate(didl);
// System.out.println("-->" + didlStrng);
// return new BrowseResult(didlStrng, 2, 2);
// } else if (objectID.equals(ID_DOWNLOADLIST)) {
//
// PersonWithRole artist = new PersonWithRole("MYArtist", "Performer");
// MimeType mimeType = new MimeType("audio", "mpeg");
// Res res = new Res(mimeType, 123456l, "00:03:25", 8192l, "http://192.168.2.122:3128/vlcstreaming/video?mp3");
// didl.addItem(new MusicTrack("101", ID_DOWNLOADLIST, "MyTitle.mp3", artist.getName(), "MyAlbum", artist, res));
//
// res = new Res(new MimeType("video", "mp4"), 123456l, "00:03:25,000", 8192l,
// "http://192.168.2.122:3128/vlcstreaming/video?mp4");
//
// didl.addItem(new VideoItem("102", ID_DOWNLOADLIST, "MyMovie.mp4", "My Creator", res));
//
// res = new Res(new MimeType("video", "mkv"), 123456l, "00:00:01", 8192l, "http://192.168.2.122:3128/vlcstreaming/video?mkv");
//
// didl.addItem(new VideoItem("103", ID_DOWNLOADLIST, "MyMovie.mkv", "My Creator", res));
// String didlStrng = new DIDLParser().generate(didl);
// System.out.println("-->" + didlStrng);
// return new BrowseResult(didlStrng, 3, 3);
// } else if (objectID.equals(ID_LINKGRABBER)) {
//
// }
//
// //
// }
}
private HashMap<String, ContentNode> map = new HashMap<String, ContentNode>();
private void createRoot() {
root = new RootContainer();
map.put(root.getID() + "", root);
}
private void addChildren(ContainerNode parent, ContentNode child) {
parent.addChildren(child);
if (map.put(child.getID() + "", child) != null) throw new WTFException("ID DUPES");
}
@Override
public ContentNode getNode(String objectID) {
return map.get(objectID);
}
}

View File

@ -1,5 +1,8 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
import org.jdownloader.extensions.vlcstreaming.upnp.content.BasicContentProvider;
import org.jdownloader.extensions.vlcstreaming.upnp.content.ContentProvider;
public class ContentFactory {
public static ContentProvider create() {

View File

@ -1,22 +0,0 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
public abstract class ContentItem implements ItemNode {
protected ContainerNode parent;
private int id;
public ContentItem(int id) {
this.id = id;
}
@Override
public void setParent(ContainerNode parent) {
this.parent = parent;
}
@Override
public int getID() {
return id;
}
}

View File

@ -1,11 +0,0 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
import org.teleal.cling.support.model.DIDLObject;
public interface ContentNode {
DIDLObject getImpl();
void setParent(ContainerNode parent);
int getID();
}

View File

@ -1,7 +0,0 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
public interface ContentProvider {
ContentNode getNode(String objectID);
}

View File

@ -1,7 +0,0 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
import org.teleal.cling.support.model.item.Item;
public interface ItemNode extends ContentNode {
Item getImpl();
}

View File

@ -1,20 +1,20 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
import org.teleal.cling.UpnpService;
import org.teleal.cling.UpnpServiceImpl;
import org.teleal.cling.controlpoint.ActionCallback;
import org.teleal.cling.model.action.ActionInvocation;
import org.teleal.cling.model.message.UpnpResponse;
import org.teleal.cling.model.message.header.STAllHeader;
import org.teleal.cling.model.meta.RemoteDevice;
import org.teleal.cling.model.meta.Service;
import org.teleal.cling.model.types.ServiceId;
import org.teleal.cling.model.types.UDAServiceId;
import org.teleal.cling.registry.DefaultRegistryListener;
import org.teleal.cling.registry.Registry;
import org.teleal.cling.registry.RegistryListener;
import org.teleal.cling.support.avtransport.callback.Play;
import org.teleal.cling.support.avtransport.callback.SetAVTransportURI;
import org.fourthline.cling.UpnpService;
import org.fourthline.cling.UpnpServiceImpl;
import org.fourthline.cling.controlpoint.ActionCallback;
import org.fourthline.cling.model.action.ActionInvocation;
import org.fourthline.cling.model.message.UpnpResponse;
import org.fourthline.cling.model.message.header.STAllHeader;
import org.fourthline.cling.model.meta.RemoteDevice;
import org.fourthline.cling.model.meta.Service;
import org.fourthline.cling.model.types.ServiceId;
import org.fourthline.cling.model.types.UDAServiceId;
import org.fourthline.cling.registry.DefaultRegistryListener;
import org.fourthline.cling.registry.Registry;
import org.fourthline.cling.registry.RegistryListener;
import org.fourthline.cling.support.avtransport.callback.Play;
import org.fourthline.cling.support.avtransport.callback.SetAVTransportURI;
public class Main implements Runnable {
public static void main(String[] args) throws Exception {

View File

@ -0,0 +1,7 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
import org.fourthline.cling.support.xmicrosoft.AbstractMediaReceiverRegistrarService;
public class MediaReceiverRegistrar extends AbstractMediaReceiverRegistrarService {
}

View File

@ -1,27 +1,37 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import org.appwork.utils.Application;
import org.appwork.utils.logging2.LogSource;
import org.fourthline.cling.UpnpServiceImpl;
import org.fourthline.cling.binding.annotations.AnnotationLocalServiceBinder;
import org.fourthline.cling.model.DefaultServiceManager;
import org.fourthline.cling.model.ValidationException;
import org.fourthline.cling.model.meta.DeviceDetails;
import org.fourthline.cling.model.meta.DeviceIdentity;
import org.fourthline.cling.model.meta.Icon;
import org.fourthline.cling.model.meta.LocalDevice;
import org.fourthline.cling.model.meta.LocalService;
import org.fourthline.cling.model.meta.ManufacturerDetails;
import org.fourthline.cling.model.meta.ModelDetails;
import org.fourthline.cling.model.profile.HeaderDeviceDetailsProvider;
import org.fourthline.cling.model.types.DLNACaps;
import org.fourthline.cling.model.types.DLNADoc;
import org.fourthline.cling.model.types.DeviceType;
import org.fourthline.cling.model.types.UDADeviceType;
import org.fourthline.cling.model.types.UDN;
import org.fourthline.cling.support.connectionmanager.ConnectionManagerService;
import org.fourthline.cling.support.model.Protocol;
import org.fourthline.cling.support.model.ProtocolInfo;
import org.fourthline.cling.support.model.ProtocolInfos;
import org.jdownloader.extensions.vlcstreaming.upnp.content.ContentDirectory;
import org.jdownloader.images.NewTheme;
import org.teleal.cling.UpnpService;
import org.teleal.cling.UpnpServiceImpl;
import org.teleal.cling.binding.annotations.AnnotationLocalServiceBinder;
import org.teleal.cling.model.DefaultServiceManager;
import org.teleal.cling.model.ValidationException;
import org.teleal.cling.model.meta.DeviceDetails;
import org.teleal.cling.model.meta.DeviceIdentity;
import org.teleal.cling.model.meta.LocalDevice;
import org.teleal.cling.model.meta.LocalService;
import org.teleal.cling.model.meta.ManufacturerDetails;
import org.teleal.cling.model.meta.ModelDetails;
import org.teleal.cling.model.types.DeviceType;
import org.teleal.cling.model.types.UDADeviceType;
import org.teleal.cling.model.types.UDN;
import org.teleal.cling.support.connectionmanager.ConnectionManagerService;
import org.teleal.cling.support.model.Protocol;
import org.teleal.cling.support.model.ProtocolInfo;
import org.teleal.cling.support.model.ProtocolInfos;
import org.jdownloader.logging.LogController;
public class MediaServer implements Runnable {
@ -35,17 +45,30 @@ public class MediaServer implements Runnable {
serverThread.start();
}
private LogSource logger;
private UpnpServiceImpl upnpService;
public MediaServer() {
logger = LogController.getInstance().getLogger("UPNP Media Server");
}
public void run() {
try {
final UpnpService upnpService = new UpnpServiceImpl();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
upnpService.shutdown();
}
});
// final UpnpService upnpService = new UpnpServiceImpl(new DefaultUpnpServiceConfiguration(8895) {
// // Override using Apache Http instead of sun http
// // This could be used to implement our own http stack instead
// @Override
// public StreamClient<StreamClientConfigurationImpl> createStreamClient() {
// return new StreamClientImpl(new StreamClientConfigurationImpl());
// }
//
// @Override
// public StreamServer createStreamServer(NetworkAddressFactory networkAddressFactory) {
// return new StreamServerImpl(new StreamServerConfigurationImpl(networkAddressFactory.getStreamListenPort()));
// }
// }, new RegistryListener[0]);
upnpService = new UpnpServiceImpl();
// Add the bound local device to the registry
upnpService.getRegistry().addDevice(createDevice());
@ -58,18 +81,54 @@ public class MediaServer implements Runnable {
}
private LocalDevice createDevice() throws IOException, ValidationException {
String host = getHostName();
DeviceIdentity identity = new DeviceIdentity(UDN.uniqueSystemIdentifier("org.jdownloader.extensions.vlcstreaming.upnp.MediaServer"));
DeviceType type = new UDADeviceType("MediaServer", SERVER_VERSION);
DeviceDetails details = new DeviceDetails("AppWork UPNP Media Server", new ManufacturerDetails("AppWorkGmbH"), new ModelDetails("AppWorkMediaServer", "A Upnp MediaServer to access the Downloadlist and Linkgrabberlist of JDownloader", "v1"));
org.teleal.cling.model.meta.Icon icon = new org.teleal.cling.model.meta.Icon("image/png", 64, 64, 32, NewTheme.I().getImageUrl("logo/jd_logo_64_64"));
ManufacturerDetails manufacturer = new ManufacturerDetails("AppWork GmbH", "http://appwork.org");
// Windows Media Player Device Details
// seem like windows mediaplayer needs a special device description
// http://4thline.org/projects/mailinglists.html#nabble-td3827350
DeviceDetails wmpDetails = new DeviceDetails(host + ": JDMedia", manufacturer, new ModelDetails("Windows Media Player Sharing", "Windows Media Player Sharing", "12.0"), "000da201238c", "100000000001", "http://appwork.org/mediaserver", new DLNADoc[] { new DLNADoc("DMS", DLNADoc.Version.V1_5), }, new DLNACaps(new String[] { "av-upload", "image-upload", "audio-upload" }));
LocalDevice device = new LocalDevice(identity, type, details, icon, new LocalService[] { createContentDirectory(), createConnectionManager() });
// Common Details
DeviceDetails ownDetails = new DeviceDetails(host + ": JDMedia", manufacturer, new ModelDetails("JDownloader Media Server", "JDownloader Media Server", "1"), "000da201238c", "100000000001", "http://appwork.org/mediaserver", new DLNADoc[] { new DLNADoc("DMS", DLNADoc.Version.V1_5), }, new DLNACaps(new String[] { "av-upload", "image-upload", "audio-upload" }));
// Device Details Provider
Map<HeaderDeviceDetailsProvider.Key, DeviceDetails> headerDetails = new HashMap<HeaderDeviceDetailsProvider.Key, DeviceDetails>();
// WDTV?
headerDetails.put(new HeaderDeviceDetailsProvider.Key("User-Agent", "FDSSDP"), wmpDetails);
headerDetails.put(new HeaderDeviceDetailsProvider.Key("User-Agent", "Xbox.*"), wmpDetails);
headerDetails.put(new HeaderDeviceDetailsProvider.Key("X-AV-Client-Info", ".*PLAYSTATION 3.*"), ownDetails);
HeaderDeviceDetailsProvider provider = new HeaderDeviceDetailsProvider(ownDetails, headerDetails);
Icon icon = new Icon("image/png", 64, 64, 32, NewTheme.I().getImageUrl("logo/jd_logo_64_64"));
LocalDevice device = new LocalDevice(identity, type, provider, icon, new LocalService[] { createContentDirectory(), createConnectionManager(), createMediaReceiverRegistrar() });
return device;
}
private LocalService<MediaReceiverRegistrar> createMediaReceiverRegistrar() {
LocalService<MediaReceiverRegistrar> mediaReceiverRegistrar = new AnnotationLocalServiceBinder().read(MediaReceiverRegistrar.class);
mediaReceiverRegistrar.setManager(new DefaultServiceManager<MediaReceiverRegistrar>(mediaReceiverRegistrar, MediaReceiverRegistrar.class));
return mediaReceiverRegistrar;
}
private String getHostName() {
String hostName;
try {
hostName = InetAddress.getLocalHost().getHostName();
if (!org.appwork.utils.StringUtils.isEmpty(hostName)) { return hostName; }
} catch (UnknownHostException e) {
logger.log(e);
}
return "Home Server";
}
private LocalService<ConnectionManagerService> createConnectionManager() {
LocalService<ConnectionManagerService> service = new AnnotationLocalServiceBinder().read(ConnectionManagerService.class);
final ProtocolInfos sourceProtocols = new ProtocolInfos(new ProtocolInfo(Protocol.HTTP_GET, ProtocolInfo.WILDCARD, "audio/mpeg", "DLNA.ORG_PN=MP3;DLNA.ORG_OP=01"), new ProtocolInfo(Protocol.HTTP_GET, ProtocolInfo.WILDCARD, "video/mpeg", "DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=01;DLNA.ORG_CI=0"), new ProtocolInfo(Protocol.HTTP_GET, ProtocolInfo.WILDCARD, "video/mp4", "DLNA.ORG_PN=mp4;DLNA.ORG_OP=01;DLNA.ORG_CI=0"));
@ -86,9 +145,22 @@ public class MediaServer implements Runnable {
@SuppressWarnings("unchecked")
LocalService<ContentDirectory> mp3ContentService = new AnnotationLocalServiceBinder().read(ContentDirectory.class);
mp3ContentService.setManager(new DefaultServiceManager<ContentDirectory>(mp3ContentService, ContentDirectory.class));
// init here to bypass the lazy init.
final ContentDirectory library = new ContentDirectory();
mp3ContentService.setManager(new DefaultServiceManager<ContentDirectory>(mp3ContentService, ContentDirectory.class) {
@Override
protected ContentDirectory createServiceInstance() throws Exception {
return library;
}
});
return mp3ContentService;
}
public void shutdown() {
upnpService.shutdown();
}
}

View File

@ -0,0 +1,25 @@
package org.jdownloader.extensions.vlcstreaming.upnp.content;
import org.fourthline.cling.support.model.container.Container;
import org.jdownloader.extensions.extraction.Archive;
public class ArchiveContainer extends FolderContainer {
public ArchiveContainer(String id, Archive archive) {
super(id, "[ARCHIVE] " + archive.getName());
}
@Override
public Container getImpl() {
Container con = new Container();
con.setParentID(getParent().getID());
con.setId(getID());
con.setChildCount(1);
con.setClazz(new org.fourthline.cling.support.model.DIDLObject.Class("object.container.storageFolder"));
con.setRestricted(true);
con.setSearchable(false);
con.setTitle(getTitle());
return con;
}
}

View File

@ -0,0 +1,288 @@
package org.jdownloader.extensions.vlcstreaming.upnp.content;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.HashSet;
import org.appwork.exceptions.WTFException;
import org.appwork.storage.config.JsonConfig;
import org.appwork.utils.Files;
import org.fourthline.cling.support.contentdirectory.DIDLParser;
import org.fourthline.cling.support.model.DIDLContent;
import org.fourthline.cling.support.model.PersonWithRole;
import org.fourthline.cling.support.model.Res;
import org.fourthline.cling.support.model.item.Item;
import org.fourthline.cling.support.model.item.MusicTrack;
import org.fourthline.cling.support.model.item.VideoItem;
import org.jdownloader.extensions.ExtensionController;
import org.jdownloader.extensions.extraction.Archive;
import org.jdownloader.extensions.extraction.ExtractionExtension;
import org.jdownloader.extensions.extraction.bindings.file.FileArchiveFactory;
import org.jdownloader.extensions.vlcstreaming.upnp.content.mediainfo.AudioMediaInfo;
import org.jdownloader.extensions.vlcstreaming.upnp.content.mediainfo.VideoMediaInfo;
import org.jdownloader.settings.GeneralSettings;
import org.seamless.util.MimeType;
public class BasicContentProvider implements ContentProvider {
private RootContainer root;
private DIDLParser didlParser;
public BasicContentProvider() {
didlParser = new DIDLParser();
createRoot();
FolderContainer downloadlist;
addChildren(root, downloadlist = new FolderContainer("1", "DownloadList"));
//
try {
mountHDFolder(new File(JsonConfig.create(GeneralSettings.class).getDefaultDownloadFolder()), root);
} catch (UnsupportedEncodingException e) {
throw new WTFException(e);
}
// for (DownloadLink dl : ) {
// String ext = Files.getExtension(dl.getFinalFileName());
//
// if("jpg".equals(ext)){
//
//
// }else if("mp4".equals(ext)){
//
//
// }else if ("mp3".equals(ext)){
//
// addChildren(downloadlist, new ContentItem(10) {
//
// @Override
// public Item getImpl() {
//
// PersonWithRole artist = new PersonWithRole("MyArtist", "Performer");
// MimeType mimeType = new MimeType("audio", "mpeg");
// Res res = new Res(mimeType, 123456l, "00:03:25", 8192l, "http://192.168.2.122:3128/vlcstreaming/video?mp3");
// dl.get
// return new MusicTrack(getID() + "", parent.getID() + "", "MyTitle.mp3", artist.getName(), "MyAlbum", artist, res);
// }
//
// });
// }
}
// if (node instanceof ContainerNode) {
//
// // Container audio = new Container();
// // audio.setId("0");
// // audio.setParentID("-1");
// // audio.setTitle("Wurzel");
// // // audio.setCreator("JDownloader");
// // audio.setRestricted(true);
// // audio.setSearchable(false);
// //
// // audio.setChildCount(2);
// // audio.setClazz(new org.fourthline.cling.support.model.DIDLObject.Class("object.container"));
//
// } else if (node instanceof ItemNode) {
// didl.addContainer(((ItemNode) node).getImpl());
// String didlStrng = new DIDLParser().generate(didl);
// didlStrng = didlStrng.replace("\"true\"", "\"1\"").replace("\"false\"", "\"0\"");
// System.out.println("-->" + didlStrng);
// return new BrowseResult(didlStrng, 1, 1);
// Container audio = new Container();
// audio.setId(ID_DOWNLOADLIST);
// audio.setParentID("0");
// audio.setTitle("DownloadList");
// audio.setCreator("JDownloader");
// audio.setRestricted(true);
// audio.setSearchable(true);
// audio.setWriteStatus(WriteStatus.NOT_WRITABLE);
// audio.setChildCount(3);
// audio.setClazz(new org.fourthline.cling.support.model.DIDLObject.Class("object.container"));
// didl.addContainer(audio);
// String didlStrng = new DIDLParser().generate(didl);
// System.out.println("-->" + didlStrng);
//
// } else if (objectID.equals(ID_LINKGRABBER)) {
// Container movie = new Container();
// movie.setId(ID_LINKGRABBER);
// movie.setParentID("0");
// movie.setTitle("Linkgrabber");
// movie.setCreator("JDownloader");
// movie.setRestricted(true);
// movie.setSearchable(true);
// movie.setWriteStatus(WriteStatus.NOT_WRITABLE);
// movie.setChildCount(0);
// movie.setClazz(new org.fourthline.cling.support.model.DIDLObject.Class("object.container"));
// didl.addContainer(movie);
// String didlStrng = new DIDLParser().generate(didl);
// System.out.println("-->" + didlStrng);
// return new BrowseResult(didlStrng, 0, 0);
// }
// } else {
//
// if (objectID.equals(ID_ROOT)) {
// // root
//
// Container audio = new Container();
// audio.setId(ID_DOWNLOADLIST);
// audio.setParentID("0");
// audio.setTitle("DownloadList");
// audio.setCreator("JDownloader");
// audio.setRestricted(true);
// audio.setSearchable(true);
// audio.setWriteStatus(WriteStatus.NOT_WRITABLE);
// audio.setChildCount(3);
// audio.setClazz(new org.fourthline.cling.support.model.DIDLObject.Class("object.container"));
// didl.addContainer(audio);
//
// Container movie = new Container();
// movie.setId(ID_LINKGRABBER);
// movie.setParentID("0");
// movie.setTitle("Linkgrabber");
// movie.setCreator("JDownloader");
// movie.setRestricted(true);
// movie.setSearchable(true);
// movie.setWriteStatus(WriteStatus.NOT_WRITABLE);
// movie.setChildCount(0);
// movie.setClazz(new org.fourthline.cling.support.model.DIDLObject.Class("object.container"));
// didl.addContainer(movie);
//
// String didlStrng = new DIDLParser().generate(didl);
// System.out.println("-->" + didlStrng);
// return new BrowseResult(didlStrng, 2, 2);
// } else if (objectID.equals(ID_DOWNLOADLIST)) {
//
// PersonWithRole artist = new PersonWithRole("MYArtist", "Performer");
// MimeType mimeType = new MimeType("audio", "mpeg");
// Res res = new Res(mimeType, 123456l, "00:03:25", 8192l, "http://192.168.2.122:3128/vlcstreaming/video?mp3");
// didl.addItem(new MusicTrack("101", ID_DOWNLOADLIST, "MyTitle.mp3", artist.getName(), "MyAlbum", artist, res));
//
// res = new Res(new MimeType("video", "mp4"), 123456l, "00:03:25,000", 8192l,
// "http://192.168.2.122:3128/vlcstreaming/video?mp4");
//
// didl.addItem(new VideoItem("102", ID_DOWNLOADLIST, "MyMovie.mp4", "My Creator", res));
//
// res = new Res(new MimeType("video", "mkv"), 123456l, "00:00:01", 8192l, "http://192.168.2.122:3128/vlcstreaming/video?mkv");
//
// didl.addItem(new VideoItem("103", ID_DOWNLOADLIST, "MyMovie.mkv", "My Creator", res));
// String didlStrng = new DIDLParser().generate(didl);
// System.out.println("-->" + didlStrng);
// return new BrowseResult(didlStrng, 3, 3);
// } else if (objectID.equals(ID_LINKGRABBER)) {
//
// }
//
// //
// }
private void mountHDFolder(File file, FolderContainer root2) throws UnsupportedEncodingException {
ExtractionExtension archiver = (ExtractionExtension) ExtensionController.getInstance().getExtension(ExtractionExtension.class)._getExtension();
HashSet<String> archives = new HashSet<String>();
for (final File f : file.listFiles()) {
if (f.isFile()) {
FileArchiveFactory fac = new FileArchiveFactory(f);
Archive archive = archiver.getArchiveByFactory(fac);
System.out.println(archive);
if (archive != null) {
String id = archiver.createArchiveID(fac);
if (archive.getFirstArchiveFile().getName().endsWith(".rar")) {
if (archives.add(id)) {
addChildren(root2, new ArchiveContainer(id, archive));
}
}
} else {
String pp = f.getAbsolutePath().replace("\\", "\\\\");
final String url = "http://192.168.2.122:3128/vlcstreaming/video?\"" + URLEncoder.encode(pp, "UTF-8") + "\"";
String ext = Files.getExtension(f.getName());
if ("mp3".equals(ext)) {
addChildren(root2, new ContentItem(f.getAbsolutePath()) {
@Override
public Item getImpl() {
AudioMediaInfo mi = new AudioMediaInfo(f);
PersonWithRole artist = new PersonWithRole(mi.getArtist(), "Performer");
MimeType mimeType = mi.getMimeType();
Res res;
res = new Res(mimeType, mi.getContentLength(), formatDuration(mi.getDuration()), mi.getBitrate(), url);
return new MusicTrack(getID(), parent.getID(), mi.getTitle(), mi.getArtist(), mi.getAlbum(), artist, res);
}
});
} else if ("mkv".equals(ext) || "mp4".equals(ext) || "avi".equals(ext)) {
addChildren(root2, new ContentItem(f.getAbsolutePath()) {
@Override
public Item getImpl() {
VideoMediaInfo mi = new VideoMediaInfo(f);
Res res = new Res(mi.getMimeType(), mi.getContentLength(), formatDuration(mi.getDuration()), mi.getBitrate(), url);
//
return (new VideoItem(getID(), getParent().getID(), mi.getTitle(), null, res));
}
});
}
System.out.println(ext);
}
} else {
FolderContainer dir = new FolderContainer(f.getAbsolutePath(), f.getName());
addChildren(root2, dir);
mountHDFolder(f, dir);
}
}
}
private String formatDuration(int ms) {
long days, hours, minutes, seconds, milliseconds;
final StringBuilder string = new StringBuilder();
milliseconds = ms % 1000;
days = ms / (24 * 60 * 60 * 1000);
ms -= days * 24 * 60 * 60 * 1000;
hours = ms / (60 * 60 * 1000);
ms -= hours * 60 * 60 * 1000;
minutes = ms / 60;
seconds = ms - minutes * 60;
return hours + ":" + minutes + ":" + seconds;
}
private HashMap<String, ContentNode> map = new HashMap<String, ContentNode>();
private void createRoot() {
root = new RootContainer();
map.put(root.getID() + "", root);
}
private void addChildren(ContainerNode parent, ContentNode child) {
parent.addChildren(child);
if (map.put(child.getID() + "", child) != null) throw new WTFException("ID DUPES");
}
@Override
public ContentNode getNode(String objectID) {
return map.get(objectID);
}
@Override
public String toDidlString(DIDLContent didl) throws Exception {
synchronized (didlParser) {
// didlParser is not thread safe
// ps3 seems to prefer 1/0 instead of true/false
return didlParser.generate(didl).replace("\"true\"", "\"1\"").replace("\"false\"", "\"0\"");
}
}
}

View File

@ -1,8 +1,8 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
package org.jdownloader.extensions.vlcstreaming.upnp.content;
import java.util.List;
import org.teleal.cling.support.model.container.Container;
import org.fourthline.cling.support.model.container.Container;
public interface ContainerNode extends ContentNode {
@ -10,6 +10,8 @@ public interface ContainerNode extends ContentNode {
Container getImpl();
public String getTitle();
public void addChildren(ContentNode child);
}

View File

@ -1,29 +1,28 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
package org.jdownloader.extensions.vlcstreaming.upnp.content;
import java.util.List;
import org.appwork.exceptions.WTFException;
import org.appwork.utils.logging.Log;
import org.teleal.cling.support.contentdirectory.AbstractContentDirectoryService;
import org.teleal.cling.support.contentdirectory.ContentDirectoryErrorCode;
import org.teleal.cling.support.contentdirectory.ContentDirectoryException;
import org.teleal.cling.support.contentdirectory.DIDLParser;
import org.teleal.cling.support.model.BrowseFlag;
import org.teleal.cling.support.model.BrowseResult;
import org.teleal.cling.support.model.DIDLContent;
import org.teleal.cling.support.model.SortCriterion;
import org.fourthline.cling.model.message.UpnpHeaders;
import org.fourthline.cling.support.contentdirectory.AbstractContentDirectoryService;
import org.fourthline.cling.support.contentdirectory.ContentDirectoryErrorCode;
import org.fourthline.cling.support.contentdirectory.ContentDirectoryException;
import org.fourthline.cling.support.contentdirectory.DIDLParser;
import org.fourthline.cling.support.model.BrowseFlag;
import org.fourthline.cling.support.model.BrowseResult;
import org.fourthline.cling.support.model.DIDLContent;
import org.fourthline.cling.support.model.SortCriterion;
import org.jdownloader.extensions.vlcstreaming.upnp.ContentFactory;
public class ContentDirectory extends AbstractContentDirectoryService {
private static final String ID_ROOT = "0";
private static final String ID_DOWNLOADLIST = "1";
private static final String ID_LINKGRABBER = "2";
private ContentProvider contentProvider;
private ContentProvider defaultProvider;
public ContentDirectory() {
contentProvider = ContentFactory.create();
defaultProvider = ContentFactory.create();
}
@Override
@ -33,7 +32,8 @@ public class ContentDirectory extends AbstractContentDirectoryService {
// This is just an example... you have to create the DIDL content dynamically!
System.out.println(objectID + " - browseFlag:" + browseFlag + " filter:" + filter + " firstResult:" + firstResult + " maxResults:" + maxResults + " orderby:" + orderby);
DIDLContent didl = new DIDLContent();
System.out.println(1);
ContentProvider contentProvider = getContentProvider(org.fourthline.cling.protocol.sync.ReceivingAction.getRequestMessage().getHeaders());
ContentNode node = contentProvider.getNode(objectID);
if (node == null) {
String didlStrng = new DIDLParser().generate(didl);
@ -44,7 +44,7 @@ public class ContentDirectory extends AbstractContentDirectoryService {
// ps3
didl.addContainer(((ContainerNode) node).getImpl());
String didlStrng = postEditDidl(new DIDLParser().generate(didl));
String didlStrng = contentProvider.toDidlString(didl);
return new BrowseResult(didlStrng, 1, 1);
@ -59,7 +59,7 @@ public class ContentDirectory extends AbstractContentDirectoryService {
}
}
String didlStrng = postEditDidl(new DIDLParser().generate(didl));
String didlStrng = contentProvider.toDidlString(didl);
return new BrowseResult(didlStrng, children.size(), children.size());
} else {
throw new WTFException();
@ -73,9 +73,8 @@ public class ContentDirectory extends AbstractContentDirectoryService {
}
}
private String postEditDidl(String didlStrng) {
return didlStrng.replace("\"true\"", "\"1\"").replace("\"false\"", "\"0\"");
private ContentProvider getContentProvider(UpnpHeaders upnpHeaders) {
return defaultProvider;
}
@Override

View File

@ -0,0 +1,27 @@
package org.jdownloader.extensions.vlcstreaming.upnp.content;
public abstract class ContentItem implements ItemNode {
protected ContainerNode parent;
private String id;
public ContentItem(String id) {
this.id = id;
}
@Override
public ContainerNode getParent() {
return parent;
}
@Override
public void setParent(ContainerNode parent) {
this.parent = parent;
}
@Override
public String getID() {
return id;
}
}

View File

@ -0,0 +1,13 @@
package org.jdownloader.extensions.vlcstreaming.upnp.content;
import org.fourthline.cling.support.model.DIDLObject;
public interface ContentNode {
DIDLObject getImpl();
void setParent(ContainerNode parent);
public ContainerNode getParent();
String getID();
}

View File

@ -0,0 +1,11 @@
package org.jdownloader.extensions.vlcstreaming.upnp.content;
import org.fourthline.cling.support.model.DIDLContent;
public interface ContentProvider {
ContentNode getNode(String objectID);
String toDidlString(DIDLContent didl) throws Exception;
}

View File

@ -1,18 +1,18 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
package org.jdownloader.extensions.vlcstreaming.upnp.content;
import java.util.ArrayList;
import java.util.List;
import org.teleal.cling.support.model.container.Container;
import org.fourthline.cling.support.model.container.Container;
public class FolderContainer implements ContainerNode {
private List<ContentNode> children = new ArrayList<ContentNode>();
private String title;
private ContainerNode parent;
private int id;
private String id;
public FolderContainer(int id, String title) {
public FolderContainer(String id, String title) {
this.title = title;
this.id = id;
}
@ -28,7 +28,7 @@ public class FolderContainer implements ContainerNode {
if (parent != null) con.setParentID(parent.getID() + "");
con.setId(getID() + "");
con.setChildCount(children.size());
con.setClazz(new org.teleal.cling.support.model.DIDLObject.Class("object.container"));
con.setClazz(new org.fourthline.cling.support.model.DIDLObject.Class("object.container"));
con.setRestricted(true);
con.setSearchable(false);
con.setTitle(title);
@ -36,7 +36,7 @@ public class FolderContainer implements ContainerNode {
}
@Override
public int getID() {
public String getID() {
return id;
}
@ -51,4 +51,14 @@ public class FolderContainer implements ContainerNode {
child.setParent(this);
}
@Override
public ContainerNode getParent() {
return parent;
}
@Override
public String getTitle() {
return title;
}
}

View File

@ -0,0 +1,7 @@
package org.jdownloader.extensions.vlcstreaming.upnp.content;
import org.fourthline.cling.support.model.item.Item;
public interface ItemNode extends ContentNode {
Item getImpl();
}

View File

@ -1,10 +1,10 @@
package org.jdownloader.extensions.vlcstreaming.upnp;
package org.jdownloader.extensions.vlcstreaming.upnp.content;
import org.teleal.cling.support.model.container.Container;
import org.fourthline.cling.support.model.container.Container;
public class RootContainer extends FolderContainer {
public RootContainer() {
super(0, "Root");
super("0", "Root");
}
@Override

View File

@ -0,0 +1,43 @@
package org.jdownloader.extensions.vlcstreaming.upnp.content.mediainfo;
import java.io.File;
import org.seamless.util.MimeType;
public class AudioMediaInfo implements MediaInfo {
private File file;
public AudioMediaInfo(File f) {
this.file = f;
}
public int getDuration() {
return 300;
}
public String getArtist() {
return "Unknown Artist";
}
public MimeType getMimeType() {
return new MimeType("audio", "mpeg");
}
public Long getContentLength() {
return file.length();
}
public Long getBitrate() {
return 4000l;
}
public String getTitle() {
return file.getName();
}
public String getAlbum() {
return "Unknown Album";
}
}

View File

@ -0,0 +1,12 @@
package org.jdownloader.extensions.vlcstreaming.upnp.content.mediainfo;
import org.seamless.util.MimeType;
public interface MediaInfo {
public MimeType getMimeType();
public Long getContentLength();
public String getTitle();
}

View File

@ -0,0 +1,38 @@
package org.jdownloader.extensions.vlcstreaming.upnp.content.mediainfo;
import java.io.File;
import org.seamless.util.MimeType;
public class VideoMediaInfo implements MediaInfo {
private File file;
public VideoMediaInfo(File f) {
this.file = f;
}
@Override
public MimeType getMimeType() {
return new MimeType("video", "mp4");
}
@Override
public Long getContentLength() {
return file.length();
}
@Override
public String getTitle() {
return file.getName();
}
public int getDuration() {
return 34213;
}
public Long getBitrate() {
return null;
}
}