mirror of
https://github.com/sifacaii/VlcJellyfin
synced 2025-05-26 06:20:20 -04:00
添加投屏
This commit is contained in:
parent
ce63dd6afb
commit
b80b587305
@ -31,6 +31,33 @@ public class Controller {
|
|||||||
PostXML(controlUrl, xml, headers, cb);
|
PostXML(controlUrl, xml, headers, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void GetMediaInfo(String controlUrl, JfClient.JJCallBack cb) {
|
||||||
|
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
||||||
|
"<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
|
||||||
|
"<s:Body>" +
|
||||||
|
"<u:GetMediaInfo xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\">" +
|
||||||
|
"<InstanceID>0</InstanceID>" +
|
||||||
|
"</u:GetMediaInfo>" +
|
||||||
|
"</s:Body></s:Envelope>";
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.put("SOAPACTION", "\"urn:schemas-upnp-org:service:AVTransport:1#GetMediaInfo\"");
|
||||||
|
PostXML(controlUrl, xml, headers, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Play(String controlUrl, JfClient.JJCallBack cb) {
|
||||||
|
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
||||||
|
"<s:Envelope s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
|
||||||
|
"<s:Body>" +
|
||||||
|
"<u:Play xmlns:u=\"urn:schemas-upnp-org:service:AVTransport:1\">" +
|
||||||
|
"<InstanceID>0</InstanceID>" +
|
||||||
|
"<Speed>1</Speed>" +
|
||||||
|
"</u:Play>" +
|
||||||
|
"</s:Body></s:Envelope>";
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.put("SOAPACTION", "\"urn:schemas-upnp-org:service:AVTransport:1#Play\"");
|
||||||
|
PostXML(controlUrl, xml, headers, cb);
|
||||||
|
}
|
||||||
|
|
||||||
public static void PostXML(String url, String xml, HttpHeaders headers, JfClient.JJCallBack callBack) {
|
public static void PostXML(String url, String xml, HttpHeaders headers, JfClient.JJCallBack callBack) {
|
||||||
OkGo.<String>post(url)
|
OkGo.<String>post(url)
|
||||||
.upString(xml)
|
.upString(xml)
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
package org.sifacai.vlcjellyfin.Dlna;
|
package org.sifacai.vlcjellyfin.Dlna;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Xml;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.owen.tvrecyclerview.widget.V7LinearLayoutManager;
|
import com.owen.tvrecyclerview.widget.V7LinearLayoutManager;
|
||||||
@ -17,16 +12,16 @@ import org.sifacai.vlcjellyfin.Component.JRecyclerView;
|
|||||||
import org.sifacai.vlcjellyfin.R;
|
import org.sifacai.vlcjellyfin.R;
|
||||||
import org.sifacai.vlcjellyfin.Ui.BaseActivity;
|
import org.sifacai.vlcjellyfin.Ui.BaseActivity;
|
||||||
import org.sifacai.vlcjellyfin.Utils.JfClient;
|
import org.sifacai.vlcjellyfin.Utils.JfClient;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xml.sax.SAXException;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
|
||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.MulticastSocket;
|
import java.net.MulticastSocket;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
public class DlnaActivity extends BaseActivity {
|
public class DlnaActivity extends BaseActivity {
|
||||||
private String TAG = "Dlna播放器";
|
private String TAG = "Dlna播放器";
|
||||||
@ -108,13 +103,23 @@ public class DlnaActivity extends BaseActivity {
|
|||||||
Controller.SetAVTransportURI(avTransport.controlURL, vurl, new JfClient.JJCallBack() {
|
Controller.SetAVTransportURI(avTransport.controlURL, vurl, new JfClient.JJCallBack() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(String str) {
|
public void onSuccess(String str) {
|
||||||
Log.d(TAG, "onSuccess: " + str);
|
Controller.GetMediaInfo(avTransport.controlURL,new JfClient.JJCallBack(){
|
||||||
ShowToask(str);
|
@Override
|
||||||
|
public void onSuccess(String str) {
|
||||||
|
Controller.Play(avTransport.controlURL,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(String str) {
|
||||||
|
Log.d(TAG, "onError: GetMediaInfo:" + str);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//ShowToask(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(String str) {
|
public void onError(String str) {
|
||||||
Log.d(TAG, "onError: " + str);
|
Log.d(TAG, "onError: SetAVTransportURI" + str);
|
||||||
ShowToask(str);
|
ShowToask(str);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -187,20 +192,11 @@ public class DlnaActivity extends BaseActivity {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void ProgressNOTIFY(String data) throws IOException, XmlPullParserException {
|
public void ProgressNOTIFY(String data) throws IOException, XmlPullParserException {
|
||||||
String[] notify = data.split("\n");
|
if(data.startsWith("M-SEARCH")) return;
|
||||||
boolean isav = false;
|
HashMap<String,String> dh = DlnaDevice.parseNOTIFY(data);
|
||||||
String location = "";
|
boolean isav = DlnaDevice.isMediaRenderer(dh.get("NT"));
|
||||||
for (String n : notify) {
|
String location = dh.get("Location");
|
||||||
String[] ns = n.split(":", 2);
|
if(location == null) location = "";
|
||||||
if (ns.length < 2) continue;
|
|
||||||
else if (ns[0].equals("Location")) location = ns[1];
|
|
||||||
else if (ns[0].equals("NT")) {
|
|
||||||
String nsnt = ns[1].trim();
|
|
||||||
if (DlnaDevice.isMediaRenderer(nsnt)) {
|
|
||||||
isav = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isav && !location.equals("")) {
|
if (isav && !location.equals("")) {
|
||||||
String finalLocation = location;
|
String finalLocation = location;
|
||||||
JfClient.SendGet(location, new JfClient.JJCallBack() {
|
JfClient.SendGet(location, new JfClient.JJCallBack() {
|
||||||
@ -220,7 +216,7 @@ public class DlnaActivity extends BaseActivity {
|
|||||||
public void findDevice(String location, String xml) {
|
public void findDevice(String location, String xml) {
|
||||||
DlnaDevice device;
|
DlnaDevice device;
|
||||||
try {
|
try {
|
||||||
device = XmlParser.ParseXML2(xml);
|
device = XmlParser.parseX(xml);
|
||||||
for (int i = 0; i < device.DlnaServices.size(); i++) {
|
for (int i = 0; i < device.DlnaServices.size(); i++) {
|
||||||
DlnaService ds = device.DlnaServices.get(i);
|
DlnaService ds = device.DlnaServices.get(i);
|
||||||
if (ds.serviceType.indexOf("service:AVTransport") > -1) {
|
if (ds.serviceType.indexOf("service:AVTransport") > -1) {
|
||||||
@ -240,10 +236,12 @@ public class DlnaActivity extends BaseActivity {
|
|||||||
handler.sendMessage(msg);
|
handler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (XmlPullParserException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
} catch (ParserConfigurationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (SAXException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package org.sifacai.vlcjellyfin.Dlna;
|
package org.sifacai.vlcjellyfin.Dlna;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class DlnaDevice {
|
public class DlnaDevice {
|
||||||
@ -14,8 +15,20 @@ public class DlnaDevice {
|
|||||||
|
|
||||||
public String[] MediaRendererDesc = {"upnp:rootdevice","device:MediaRenderer"};
|
public String[] MediaRendererDesc = {"upnp:rootdevice","device:MediaRenderer"};
|
||||||
public static boolean isMediaRenderer(String nt){
|
public static boolean isMediaRenderer(String nt){
|
||||||
|
if(nt == null) return false;
|
||||||
if(nt.equals("upnp:rootdevice")) return true;
|
if(nt.equals("upnp:rootdevice")) return true;
|
||||||
if(nt.indexOf("device:MediaRenderer") >= 0) return true;
|
if(nt.indexOf("device:MediaRenderer") >= 0) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static HashMap<String,String> parseNOTIFY(String data){
|
||||||
|
HashMap<String,String> hm = new HashMap<>();
|
||||||
|
String[] notify = data.split("\n");
|
||||||
|
for (String n:notify) {
|
||||||
|
String[] ns = n.split(":", 2);
|
||||||
|
if (ns.length < 2) continue;
|
||||||
|
hm.put(ns[0],ns[1].trim());
|
||||||
|
}
|
||||||
|
return hm;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,132 +1,25 @@
|
|||||||
package org.sifacai.vlcjellyfin.Dlna;
|
package org.sifacai.vlcjellyfin.Dlna;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Xml;
|
|
||||||
|
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
public class XmlParser {
|
public class XmlParser {
|
||||||
private static String TAG = "XML解析器";
|
private static String TAG = "XML解析器";
|
||||||
|
|
||||||
public static void readServiceValue(XmlPullParser parser, DlnaService service, String tagName) throws XmlPullParserException, IOException {
|
|
||||||
String value = parser.nextText();
|
|
||||||
if (tagName.equals("servicetype")) service.serviceType = value;
|
|
||||||
if (tagName.equals("serviceid")) service.serviceId = value;
|
|
||||||
if (tagName.equals("controlurl")) service.controlURL = value;
|
|
||||||
if (tagName.equals("scpdurl")) service.SCPDURL = value;
|
|
||||||
if (tagName.equals("eventsuburl")) service.eventSubURL = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DlnaService readService(XmlPullParser parser) throws XmlPullParserException, IOException {
|
|
||||||
DlnaService ds = new DlnaService();
|
|
||||||
String tagName = "";
|
|
||||||
int eventType = parser.next();
|
|
||||||
while (!tagName.equals("service") && eventType != XmlPullParser.END_DOCUMENT) {
|
|
||||||
tagName = parser.getName();
|
|
||||||
if (tagName == null) tagName = "";
|
|
||||||
if (eventType == XmlPullParser.START_TAG) {
|
|
||||||
tagName = tagName.toLowerCase();
|
|
||||||
readServiceValue(parser, ds, tagName);
|
|
||||||
}
|
|
||||||
eventType = parser.next();
|
|
||||||
}
|
|
||||||
return ds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void readDevice(XmlPullParser parser, DlnaDevice de, String tagName) throws XmlPullParserException, IOException {
|
|
||||||
int et = parser.next();
|
|
||||||
if(et == XmlPullParser.END_TAG) return;
|
|
||||||
String value = parser.getText();
|
|
||||||
value = value == null ? "" : value.trim();
|
|
||||||
if (tagName.equals("friendlyname")) de.friendlyName = value;
|
|
||||||
if (tagName.equals("devicetype")) de.deviceType = value;
|
|
||||||
if (tagName.equals("modelname")) de.modelName = value;
|
|
||||||
if (tagName.equals("udn")) de.UDN = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DlnaDevice ParseXML2(String xml) throws XmlPullParserException, IOException {
|
|
||||||
XmlPullParser xmlPullParser = Xml.newPullParser();
|
|
||||||
xmlPullParser.setInput(new StringReader(xml));
|
|
||||||
|
|
||||||
DlnaDevice device = new DlnaDevice();
|
|
||||||
|
|
||||||
int eventType = xmlPullParser.getEventType();
|
|
||||||
String tagName = "";
|
|
||||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
|
||||||
if (eventType == XmlPullParser.START_TAG) {
|
|
||||||
tagName = xmlPullParser.getName().toLowerCase();
|
|
||||||
if (tagName.equals("service")) {
|
|
||||||
DlnaService service = readService(xmlPullParser);
|
|
||||||
device.DlnaServices.add(service);
|
|
||||||
} else {
|
|
||||||
readDevice(xmlPullParser, device, tagName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eventType = xmlPullParser.next();
|
|
||||||
}
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DlnaDevice ParseXML(String xml) throws XmlPullParserException, IOException {
|
|
||||||
XmlPullParser xmlPullParser = Xml.newPullParser();
|
|
||||||
xmlPullParser.setInput(new StringReader(xml));
|
|
||||||
|
|
||||||
DlnaDevice device = new DlnaDevice();
|
|
||||||
|
|
||||||
int eventType = xmlPullParser.getEventType();
|
|
||||||
String tagName = "";
|
|
||||||
DlnaService service = null;
|
|
||||||
String icon = "";
|
|
||||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
|
||||||
String value = "";
|
|
||||||
switch (eventType) {
|
|
||||||
case XmlPullParser.START_TAG:
|
|
||||||
tagName = xmlPullParser.getName().toLowerCase();
|
|
||||||
Log.d(TAG, "ParseXML: tagName:" + tagName);
|
|
||||||
if (tagName.equals("service")) service = new DlnaService();
|
|
||||||
if (tagName.equals("icon")) icon = "";
|
|
||||||
break;
|
|
||||||
case XmlPullParser.TEXT:
|
|
||||||
|
|
||||||
break;
|
|
||||||
case XmlPullParser.END_TAG:
|
|
||||||
value = xmlPullParser.getText();
|
|
||||||
value = value == null ? "" : value.trim();
|
|
||||||
Log.d(TAG, "ParseXML: tagName:" + tagName + " value:" + value);
|
|
||||||
if (tagName.equals("friendlyname")) {
|
|
||||||
device.friendlyName = value;
|
|
||||||
//Log.d(TAG, "ParseXML: friendlyname" + value);
|
|
||||||
}
|
|
||||||
if (tagName.equals("devicetype")) device.deviceType = value;
|
|
||||||
if (tagName.equals("modelname")) device.modelName = value;
|
|
||||||
if (tagName.equals("udn")) device.UDN = value;
|
|
||||||
|
|
||||||
if (tagName.equals("url")) icon = value;
|
|
||||||
|
|
||||||
if (tagName.equals("servicetype")) service.serviceType = value;
|
|
||||||
if (tagName.equals("serviceid")) service.serviceId = value;
|
|
||||||
if (tagName.equals("controlurl")) service.controlURL = value;
|
|
||||||
if (tagName.equals("scpdurl")) service.SCPDURL = value;
|
|
||||||
if (tagName.equals("eventsuburl")) service.eventSubURL = value;
|
|
||||||
|
|
||||||
String endTag = xmlPullParser.getName().toLowerCase();
|
|
||||||
Log.d(TAG, "ParseXML: endTag:" + endTag);
|
|
||||||
if (endTag.equals("service"))
|
|
||||||
device.DlnaServices.add(service);
|
|
||||||
if (endTag.equals("icon")) device.icon.add(icon);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
eventType = xmlPullParser.next();
|
|
||||||
}
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getRspXML(String action, HashMap<String, String> map) {
|
private String getRspXML(String action, HashMap<String, String> map) {
|
||||||
String rsp = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
String rsp = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
||||||
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"" +
|
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"" +
|
||||||
@ -146,4 +39,68 @@ public class XmlParser {
|
|||||||
|
|
||||||
return rsp;
|
return rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ReadNode(XmlPullParser p, HashMap phm, String endTag) throws XmlPullParserException, IOException {
|
||||||
|
int et = p.next();
|
||||||
|
String tagName = p.getName();
|
||||||
|
do {
|
||||||
|
if (et == p.START_TAG) {
|
||||||
|
HashMap chm = new HashMap();
|
||||||
|
phm.put(tagName, chm);
|
||||||
|
ReadNode(p, chm, tagName);
|
||||||
|
} else if (et == p.TEXT) {
|
||||||
|
phm.put("TEXT-VALUE", p.getText());
|
||||||
|
} else if (et == p.END_TAG) {
|
||||||
|
Log.d(TAG, "ReadNode: END:" + p.getName());
|
||||||
|
if (tagName.equals(endTag)) return;
|
||||||
|
}
|
||||||
|
et = p.next();
|
||||||
|
tagName = p.getName();
|
||||||
|
} while (et != p.END_DOCUMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DlnaDevice parseX(String xml) throws ParserConfigurationException, IOException, SAXException {
|
||||||
|
DlnaDevice dd = new DlnaDevice();
|
||||||
|
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
|
||||||
|
DocumentBuilder builder = builderFactory.newDocumentBuilder();
|
||||||
|
Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes()));
|
||||||
|
|
||||||
|
NodeList nl = doc.getElementsByTagName("friendlyName");
|
||||||
|
dd.friendlyName = nl.getLength() > 0 ? nl.item(0).getTextContent() : "";
|
||||||
|
nl = doc.getElementsByTagName("modelName");
|
||||||
|
dd.modelName = nl.getLength() > 0 ? nl.item(0).getTextContent() : "";
|
||||||
|
nl = doc.getElementsByTagName("UDN");
|
||||||
|
dd.UDN = nl.getLength() > 0 ? nl.item(0).getTextContent() : "";
|
||||||
|
nl = doc.getElementsByTagName("deviceType");
|
||||||
|
dd.deviceType = nl.getLength() > 0 ? nl.item(0).getTextContent() : "";
|
||||||
|
|
||||||
|
|
||||||
|
nl = doc.getElementsByTagName("service");
|
||||||
|
for (int i = 0; i < nl.getLength(); i++) {
|
||||||
|
NodeList ns = nl.item(i).getChildNodes();
|
||||||
|
DlnaService ds = new DlnaService();
|
||||||
|
dd.DlnaServices.add(ds);
|
||||||
|
for (int j = 0; j < ns.getLength(); j++) {
|
||||||
|
Node nd = ns.item(j);
|
||||||
|
switch (nd.getNodeName()){
|
||||||
|
case "serviceType":
|
||||||
|
ds.serviceType = nd.getTextContent();
|
||||||
|
break;
|
||||||
|
case "serviceId":
|
||||||
|
ds.serviceId = nd.getTextContent();
|
||||||
|
break;
|
||||||
|
case "controlURL":
|
||||||
|
ds.controlURL = nd.getTextContent();
|
||||||
|
break;
|
||||||
|
case "eventSubURL":
|
||||||
|
ds.eventSubURL = nd.getTextContent();
|
||||||
|
break;
|
||||||
|
case "SCPDURL":
|
||||||
|
ds.SCPDURL = nd.getTextContent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user