diff --git a/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/Controller.java b/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/Controller.java index 323c0cd..f8d90b5 100644 --- a/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/Controller.java +++ b/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/Controller.java @@ -8,43 +8,54 @@ import com.lzy.okgo.callback.Callback; import com.lzy.okgo.model.HttpHeaders; import com.lzy.okgo.model.Response; +import org.sifacai.vlcjellyfin.Utils.JfClient; + import java.io.IOException; public class Controller { public static String TAG = "DLNA控制"; - public static void SetAVTransportURI(String controlUrl,String url){ + public static void SetAVTransportURI(String controlUrl, String url, JfClient.JJCallBack cb) { String xml = "" + "" + "" + "" + "0" + - "" + + "" + "" + "" + ""; HttpHeaders headers = new HttpHeaders(); - headers.put("SOAPAction", "\"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\""); - PostXML(controlUrl,xml,headers); + headers.put("SOAPACTION", "\"urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI\""); + PostXML(controlUrl, xml, headers, cb); } - public static void PostXML(String url, String xml, HttpHeaders headers){ - + public static void PostXML(String url, String xml, HttpHeaders headers, JfClient.JJCallBack callBack) { OkGo.post(url) .upString(xml) .headers(headers) - .headers("Content-Type","text/xml; encoding=\"utf-8\"") + .headers("Content-Type", "text/xml; encoding=\"utf-8\"") .execute(new AbsCallback() { @Override public void onSuccess(Response response) { - Log.d(TAG, "onSuccess: " + response.body()); + if (callBack != null) { + callBack.onSuccess(response.body()); + } } @Override public String convertResponse(okhttp3.Response response) throws Throwable { - Log.d(TAG, "convertResponse: " + response.message()); - return null; + String result = ""; + if (null != response.body()) { + result = response.body().string(); + } + return result; + } + + @Override + public void onError(Response response) { + if (callBack != null) callBack.onError(response.message()); } }); diff --git a/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/DlnaActivity.java b/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/DlnaActivity.java index fe9ef74..ff78c5a 100644 --- a/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/DlnaActivity.java +++ b/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/DlnaActivity.java @@ -26,6 +26,7 @@ import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; import java.util.HashMap; +import java.util.List; public class DlnaActivity extends BaseActivity { private String TAG = "Dlna播放器"; @@ -64,7 +65,6 @@ public class DlnaActivity extends BaseActivity { avt.eventSubURL = b.getString("eventSubURL"); avt.iconurl = b.getString("iconurl"); avTransportAdapter.addDevice(avt); - Log.d(TAG, "handleMessage: " + avt); break; } } @@ -105,7 +105,19 @@ public class DlnaActivity extends BaseActivity { //intent.putExtra("AVT",avTransport); //startActivity(intent); String vurl = JfClient.playList.get(JfClient.playIndex).Url; - Controller.SetAVTransportURI(avTransport.controlURL,vurl); + Controller.SetAVTransportURI(avTransport.controlURL, vurl, new JfClient.JJCallBack() { + @Override + public void onSuccess(String str) { + Log.d(TAG, "onSuccess: " + str); + ShowToask(str); + } + + @Override + public void onError(String str) { + Log.d(TAG, "onError: " + str); + ShowToask(str); + } + }); } }); } @@ -113,7 +125,7 @@ public class DlnaActivity extends BaseActivity { @Override protected void onStart() { super.onStart(); - listen_thread.start(); + if (!listen_thread.isAlive()) listen_thread.start(); refresh(); } @@ -157,15 +169,14 @@ public class DlnaActivity extends BaseActivity { private Runnable listen_Runnable = new Runnable() { @Override public void run() { - byte[] buff = new byte[1024]; - DatagramPacket packet = new DatagramPacket(buff, buff.length); while (mSocket != null) { try { + byte[] buff = new byte[1024]; + DatagramPacket packet = new DatagramPacket(buff, buff.length); mSocket.receive(packet); String clientIP = packet.getAddress().getHostAddress(); int clientPort = packet.getPort(); String data = new String(packet.getData()).trim(); - Log.d(TAG, "listen: " + clientIP + ":" + clientPort + ":" + data); ProgressNOTIFY(data); } catch (IOException | XmlPullParserException e) { throw new RuntimeException(e); @@ -181,26 +192,23 @@ public class DlnaActivity extends BaseActivity { String location = ""; for (String n : notify) { String[] ns = n.split(":", 2); - //Log.d(TAG, "ProgressNOTIFY: " + String.join(",",ns)); if (ns.length < 2) continue; else if (ns[0].equals("Location")) location = ns[1]; - else if (ns[0].equals("ST")) { + else if (ns[0].equals("NT")) { String nsnt = ns[1].trim(); - if (nsnt.equals("upnp:rootdevice") || nsnt.indexOf("device:MediaRenderer") >= 0) { + if (DlnaDevice.isMediaRenderer(nsnt)) { isav = true; } } } if (isav && !location.equals("")) { - Log.d(TAG, "ProgressNOTIFY: " + location); String finalLocation = location; - JfClient.SendGet(location,new JfClient.JJCallBack(){ + JfClient.SendGet(location, new JfClient.JJCallBack() { @Override public void onSuccess(String str) { - Log.d(TAG, "onSuccess: " + str); - findDevice(finalLocation,str); + findDevice(finalLocation, str); } - },new JfClient.JJCallBack(){ + }, new JfClient.JJCallBack() { @Override public void onError(String str) { ShowToask(str); @@ -209,10 +217,10 @@ public class DlnaActivity extends BaseActivity { } } - public void findDevice(String location,String xml){ + public void findDevice(String location, String xml) { DlnaDevice device; try { - device = ParseXML(xml); + device = XmlParser.ParseXML2(xml); for (int i = 0; i < device.DlnaServices.size(); i++) { DlnaService ds = device.DlnaServices.get(i); if (ds.serviceType.indexOf("service:AVTransport") > -1) { @@ -220,12 +228,12 @@ public class DlnaActivity extends BaseActivity { String url = si > -1 ? location.substring(0, si) : location; String moduleName = device.friendlyName.equals("") ? device.modelName : device.friendlyName; Bundle bundle = new Bundle(); - bundle.putString("moduleName",moduleName); + bundle.putString("moduleName", moduleName); bundle.putString("UDN", device.UDN); - bundle.putString("serviceId",ds.serviceId); - bundle.putString("controlURL",url + "/" + ds.controlURL); - bundle.putString("eventSubURL",url + "/" + ds.eventSubURL); - bundle.putString("iconurl",device.icon.size() > 0 ? url + "/" + device.icon.get(0) : ""); + bundle.putString("serviceId", ds.serviceId); + bundle.putString("controlURL", url + (ds.controlURL.startsWith("/") ? ds.controlURL : "/" + ds.controlURL)); + bundle.putString("eventSubURL", url + "/" + ds.eventSubURL); + bundle.putString("iconurl", device.icon.size() > 0 ? url + "/" + device.icon.get(0) : ""); Message msg = new Message(); msg.what = 1; msg.setData(bundle); @@ -238,68 +246,4 @@ public class DlnaActivity extends BaseActivity { throw new RuntimeException(e); } } - - public DlnaDevice ParseXML(String xml) throws XmlPullParserException, IOException { - Log.d(TAG, "ParseXML: " + xml); - 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) { - switch (eventType) { - case XmlPullParser.START_TAG: - tagName = xmlPullParser.getName().toLowerCase(); - if (tagName.equals("service")) service = new DlnaService(); - if (tagName.equals("icon")) icon = ""; - break; - case XmlPullParser.TEXT: - String value = xmlPullParser.getText(); - value = value == null ? "" : value.trim(); - if (tagName.equals("friendlyname")) device.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; - break; - case XmlPullParser.END_TAG: - if (xmlPullParser.getName().toLowerCase().equals("service")) device.DlnaServices.add(service); - if (xmlPullParser.getName().toLowerCase().equals("icon")) device.icon.add(icon); - break; - } - eventType = xmlPullParser.next(); - } - return device; - } - - private String getRspXML(String action, HashMap map) { - String rsp = "" + - "" + - "" + - ""; - - if (map != null) { - for (String key : map.keySet()) { - rsp += "<" + key + ">" + map.get(key) + ""; - } - } - - rsp += "" + - "" + - ""; - - return rsp; - } } \ No newline at end of file diff --git a/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/DlnaDevice.java b/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/DlnaDevice.java index 706840a..95f62d6 100644 --- a/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/DlnaDevice.java +++ b/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/DlnaDevice.java @@ -1,6 +1,7 @@ package org.sifacai.vlcjellyfin.Dlna; import java.util.ArrayList; +import java.util.List; public class DlnaDevice { public String friendlyName; @@ -10,4 +11,11 @@ public class DlnaDevice { public String location; public ArrayList icon = new ArrayList<>(); public ArrayList DlnaServices = new ArrayList<>(); + + public String[] MediaRendererDesc = {"upnp:rootdevice","device:MediaRenderer"}; + public static boolean isMediaRenderer(String nt){ + if(nt.equals("upnp:rootdevice")) return true; + if(nt.indexOf("device:MediaRenderer") >= 0) return true; + return false; + } } diff --git a/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/XmlParser.java b/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/XmlParser.java new file mode 100644 index 0000000..2c0b8ac --- /dev/null +++ b/app/src/main/java/org/sifacai/vlcjellyfin/Dlna/XmlParser.java @@ -0,0 +1,149 @@ +package org.sifacai.vlcjellyfin.Dlna; + +import android.util.Log; +import android.util.Xml; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; + + +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 map) { + String rsp = "" + + "" + + "" + + ""; + + if (map != null) { + for (String key : map.keySet()) { + rsp += "<" + key + ">" + map.get(key) + ""; + } + } + + rsp += "" + + "" + + ""; + + return rsp; + } +}