添加投屏

This commit is contained in:
sifacaii 2023-05-17 16:19:15 +08:00
parent ce63dd6afb
commit b80b587305
4 changed files with 138 additions and 143 deletions

View File

@ -31,6 +31,33 @@ public class Controller {
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) {
OkGo.<String>post(url)
.upString(xml)

View File

@ -1,14 +1,9 @@
package org.sifacai.vlcjellyfin.Dlna;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.util.Log;
import android.util.Xml;
import android.view.View;
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.Ui.BaseActivity;
import org.sifacai.vlcjellyfin.Utils.JfClient;
import org.xmlpull.v1.XmlPullParser;
import org.xml.sax.SAXException;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.io.StringReader;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.HashMap;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
public class DlnaActivity extends BaseActivity {
private String TAG = "Dlna播放器";
@ -108,13 +103,23 @@ public class DlnaActivity extends BaseActivity {
Controller.SetAVTransportURI(avTransport.controlURL, vurl, new JfClient.JJCallBack() {
@Override
public void onSuccess(String str) {
Log.d(TAG, "onSuccess: " + str);
ShowToask(str);
Controller.GetMediaInfo(avTransport.controlURL,new JfClient.JJCallBack(){
@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
public void onError(String str) {
Log.d(TAG, "onError: " + str);
Log.d(TAG, "onError: SetAVTransportURI" + str);
ShowToask(str);
}
});
@ -187,20 +192,11 @@ public class DlnaActivity extends BaseActivity {
};
public void ProgressNOTIFY(String data) throws IOException, XmlPullParserException {
String[] notify = data.split("\n");
boolean isav = false;
String location = "";
for (String n : notify) {
String[] ns = n.split(":", 2);
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(data.startsWith("M-SEARCH")) return;
HashMap<String,String> dh = DlnaDevice.parseNOTIFY(data);
boolean isav = DlnaDevice.isMediaRenderer(dh.get("NT"));
String location = dh.get("Location");
if(location == null) location = "";
if (isav && !location.equals("")) {
String finalLocation = location;
JfClient.SendGet(location, new JfClient.JJCallBack() {
@ -220,7 +216,7 @@ public class DlnaActivity extends BaseActivity {
public void findDevice(String location, String xml) {
DlnaDevice device;
try {
device = XmlParser.ParseXML2(xml);
device = XmlParser.parseX(xml);
for (int i = 0; i < device.DlnaServices.size(); i++) {
DlnaService ds = device.DlnaServices.get(i);
if (ds.serviceType.indexOf("service:AVTransport") > -1) {
@ -240,10 +236,12 @@ public class DlnaActivity extends BaseActivity {
handler.sendMessage(msg);
}
}
} catch (XmlPullParserException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,6 +1,7 @@
package org.sifacai.vlcjellyfin.Dlna;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class DlnaDevice {
@ -14,8 +15,20 @@ public class DlnaDevice {
public String[] MediaRendererDesc = {"upnp:rootdevice","device:MediaRenderer"};
public static boolean isMediaRenderer(String nt){
if(nt == null) return false;
if(nt.equals("upnp:rootdevice")) return true;
if(nt.indexOf("device:MediaRenderer") >= 0) return true;
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;
}
}

View File

@ -1,132 +1,25 @@
package org.sifacai.vlcjellyfin.Dlna;
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.XmlPullParserException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
public class XmlParser {
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) {
String rsp = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"" +
@ -146,4 +39,68 @@ public class XmlParser {
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;
}
}