mirror of
https://github.com/sifacaii/VlcJellyfin
synced 2025-05-26 06:20:20 -04:00
修BUG
This commit is contained in:
parent
356dd2c1b3
commit
88a1917c40
@ -18,9 +18,9 @@ public class AVTransportAdapter extends RecyclerView.Adapter{
|
||||
private Context context;
|
||||
private ArrayList<AVTransport> avTransports;
|
||||
|
||||
public AVTransportAdapter(Context context) {
|
||||
public AVTransportAdapter(Context context,ArrayList<AVTransport> avTransports) {
|
||||
this.context = context;
|
||||
this.avTransports = new ArrayList<>();
|
||||
this.avTransports = avTransports;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -0,0 +1,189 @@
|
||||
package org.sifacai.vlcjellyfin.Dlna;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import com.lzy.okgo.OkGo;
|
||||
|
||||
import org.sifacai.vlcjellyfin.Utils.JfClient;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
public class BroadCastThread extends Thread {
|
||||
private String TAG = "广播线程";
|
||||
|
||||
public static final int TYPE_DEVICE = 1; //发现新设备
|
||||
public static final int TYPE_NEW_DEVICE_ADDED = 2; //新加了新设备
|
||||
public static final int TYPE_DEVICE_DEL = 3; //设备离线
|
||||
public static final int TYPE_MSG = 9; //消息
|
||||
|
||||
public static final String GroupAddress = "239.255.255.250";
|
||||
|
||||
private byte[] NOTIFY_rootdevice = ("M-SEARCH * HTTP/1.1\n" +
|
||||
"ST: upnp:rootdevice\n" +
|
||||
"MX: 10\n" +
|
||||
"MAN: \"ssdp:discover\"\n" +
|
||||
"Content-Length: 0\n" +
|
||||
"HOST: 239.255.255.250:1900").getBytes();
|
||||
|
||||
private byte[] NOTIFY_MediaRenderer = ("M-SEARCH * HTTP/1.1\n" +
|
||||
"ST: urn:schemas-upnp-org:device:MediaRenderer:1\n" +
|
||||
"MX: 10\n" +
|
||||
"MAN: \"ssdp:discover\"\n" +
|
||||
"Content-Length: 0\n" +
|
||||
"HOST: 239.255.255.250:1900").getBytes();
|
||||
|
||||
private Handler handler;
|
||||
private MulticastSocket mSocket;
|
||||
private ArrayList<AVTransport> avTransports;
|
||||
private boolean isStop = false;
|
||||
|
||||
public BroadCastThread() {
|
||||
avTransports = new ArrayList<>();
|
||||
try {
|
||||
mSocket = new MulticastSocket(1900);
|
||||
mSocket.joinGroup(InetAddress.getByName(GroupAddress));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (mSocket != null && !isStop) {
|
||||
listenr();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetHandler(Handler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public ArrayList<AVTransport> GetAVTransportArray() {
|
||||
return avTransports;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送M-SEARCH
|
||||
*/
|
||||
public void refresh() {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DatagramPacket packet = new DatagramPacket(NOTIFY_rootdevice, NOTIFY_rootdevice.length);
|
||||
try {
|
||||
packet.setAddress(InetAddress.getByName(GroupAddress));
|
||||
packet.setPort(1900);
|
||||
mSocket.send(packet);
|
||||
packet.setData(NOTIFY_MediaRenderer);
|
||||
mSocket.send(packet);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听广播
|
||||
*/
|
||||
private void listenr() {
|
||||
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();
|
||||
ProgressNOTIFY(data);
|
||||
} catch (IOException | XmlPullParserException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProgressNOTIFY(String data) throws IOException, XmlPullParserException {
|
||||
Log.d(TAG, "ProgressNOTIFY: " + data);
|
||||
if (data.startsWith("M-SEARCH")) return;
|
||||
HashMap<String, String> dh = DlnaDevice.parseNOTIFY(data);
|
||||
if (isExitsOrByeBye(dh)) return;
|
||||
boolean isav = DlnaDevice.isMediaRenderer(dh.get("nt"));
|
||||
String location = dh.get("location");
|
||||
if (location == null) location = "";
|
||||
if (isav && !location.equals("")) {
|
||||
String xmlstr = JfClient.SendGet(location);
|
||||
if (xmlstr == null || xmlstr.equals("")) return;
|
||||
findDevice(location, xmlstr);
|
||||
}
|
||||
}
|
||||
|
||||
public void findDevice(String location, String xml) {
|
||||
DlnaDevice device;
|
||||
try {
|
||||
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) {
|
||||
int si = location.indexOf("/", 8);
|
||||
String url = si > -1 ? location.substring(0, si) : location;
|
||||
String moduleName = device.friendlyName.equals("") ? device.modelName : device.friendlyName;
|
||||
AVTransport av = new AVTransport();
|
||||
av.moduleName = moduleName;
|
||||
av.serviceId = ds.serviceId;
|
||||
av.UDN = device.UDN;
|
||||
av.controlURL = url + (ds.controlURL.startsWith("/") ? ds.controlURL : "/" + ds.controlURL);
|
||||
av.eventSubURL = url + (ds.eventSubURL.startsWith("/") ? ds.eventSubURL : "/" + ds.eventSubURL);
|
||||
av.iconurl = device.icon.size() > 0 ? url + "/" + device.icon.get(0) : "";
|
||||
avTransports.add(av);
|
||||
if (handler != null) {
|
||||
Message msg = new Message();
|
||||
msg.what = TYPE_NEW_DEVICE_ADDED;
|
||||
handler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (SAXException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否已存在或byebye
|
||||
* @param dh
|
||||
* @return
|
||||
*/
|
||||
public boolean isExitsOrByeBye(HashMap<String,String> dh) {
|
||||
String USN = dh.get("usn");
|
||||
String[] usns = USN.split("::");
|
||||
if (usns.length < 2) return true;
|
||||
for (AVTransport av : avTransports) {
|
||||
if (usns[0].equals(av.UDN)) {
|
||||
if(dh.get("nts")!=null && dh.get("nts").toLowerCase().indexOf("byebye") >= 0){
|
||||
avTransports.remove(av);
|
||||
Message msg = new Message();
|
||||
msg.what = TYPE_DEVICE_DEL;
|
||||
handler.sendMessage(msg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Stop() {
|
||||
isStop = true;
|
||||
}
|
||||
}
|
@ -28,42 +28,25 @@ public class DlnaActivity extends BaseActivity {
|
||||
|
||||
private JRecyclerView rv;
|
||||
private AVTransportAdapter avTransportAdapter;
|
||||
private MulticastSocket mSocket;
|
||||
private Thread listen_thread;
|
||||
|
||||
private byte[] NOTIFY_rootdevice = ("M-SEARCH * HTTP/1.1\n" +
|
||||
"ST: upnp:rootdevice\n" +
|
||||
"MX: 10\n" +
|
||||
"MAN: \"ssdp:discover\"\n" +
|
||||
"Content-Length: 0\n" +
|
||||
"HOST: 239.255.255.250:1900").getBytes();
|
||||
BroadCastThread broadCastTheader = new BroadCastThread();
|
||||
|
||||
private byte[] NOTIFY_MediaRenderer = ("M-SEARCH * HTTP/1.1\n" +
|
||||
"ST: urn:schemas-upnp-org:device:MediaRenderer:1\n" +
|
||||
"MX: 10\n" +
|
||||
"MAN: \"ssdp:discover\"\n" +
|
||||
"Content-Length: 0\n" +
|
||||
"HOST: 239.255.255.250:1900").getBytes();
|
||||
|
||||
private Handler handler = new Handler() {
|
||||
private Handler handler= new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
switch (msg.what) {
|
||||
case 1:
|
||||
Bundle b = msg.getData();
|
||||
AVTransport avt = new AVTransport();
|
||||
avt.moduleName = b.getString("moduleName");
|
||||
avt.serviceId = b.getString("serviceId");
|
||||
avt.UDN = b.getString("UDN");
|
||||
avt.controlURL = b.getString("controlURL");
|
||||
avt.eventSubURL = b.getString("eventSubURL");
|
||||
avt.iconurl = b.getString("iconurl");
|
||||
avTransportAdapter.addDevice(avt);
|
||||
case BroadCastThread.TYPE_DEVICE:
|
||||
break;
|
||||
case BroadCastThread.TYPE_NEW_DEVICE_ADDED:
|
||||
avTransportAdapter.notifyDataSetChanged();
|
||||
break;
|
||||
case BroadCastThread.TYPE_DEVICE_DEL:
|
||||
avTransportAdapter.notifyDataSetChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
};;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -71,19 +54,12 @@ public class DlnaActivity extends BaseActivity {
|
||||
setContentView(R.layout.activity_dlna);
|
||||
getSupportActionBar().hide();
|
||||
|
||||
try {
|
||||
mSocket = new MulticastSocket(1900);
|
||||
mSocket.joinGroup(InetAddress.getByName("239.255.255.250"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
listen_thread = new Thread(listen_Runnable);
|
||||
broadCastTheader.SetHandler(handler);
|
||||
|
||||
findViewById(R.id.refresh).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
refresh();
|
||||
broadCastTheader.refresh();
|
||||
}
|
||||
});
|
||||
|
||||
@ -91,7 +67,7 @@ public class DlnaActivity extends BaseActivity {
|
||||
V7LinearLayoutManager layoutManager = new V7LinearLayoutManager(rv.getContext());
|
||||
layoutManager.setOrientation(V7LinearLayoutManager.VERTICAL);
|
||||
rv.setLayoutManager(layoutManager);
|
||||
avTransportAdapter = new AVTransportAdapter(this);
|
||||
avTransportAdapter = new AVTransportAdapter(this, broadCastTheader.GetAVTransportArray());
|
||||
rv.setAdapter(avTransportAdapter);
|
||||
avTransportAdapter.setOnItemClickListener(new AVTransportAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
@ -103,10 +79,10 @@ public class DlnaActivity extends BaseActivity {
|
||||
Controller.SetAVTransportURI(avTransport.controlURL, vurl, new JfClient.JJCallBack() {
|
||||
@Override
|
||||
public void onSuccess(String str) {
|
||||
Controller.GetMediaInfo(avTransport.controlURL,new JfClient.JJCallBack(){
|
||||
Controller.GetMediaInfo(avTransport.controlURL, new JfClient.JJCallBack() {
|
||||
@Override
|
||||
public void onSuccess(String str) {
|
||||
Controller.Play(avTransport.controlURL,new JfClient.JJCallBack(){
|
||||
Controller.Play(avTransport.controlURL, new JfClient.JJCallBack() {
|
||||
@Override
|
||||
public void onSuccess(String str) {
|
||||
ShowToask("已发送!");
|
||||
@ -140,19 +116,18 @@ public class DlnaActivity extends BaseActivity {
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
if (!listen_thread.isAlive()) listen_thread.start();
|
||||
refresh();
|
||||
broadCastTheader.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
listen_thread.interrupt();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
broadCastTheader.Stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -160,99 +135,4 @@ public class DlnaActivity extends BaseActivity {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新设备
|
||||
*/
|
||||
private void refresh() {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
DatagramPacket packet = new DatagramPacket(NOTIFY_rootdevice, NOTIFY_rootdevice.length);
|
||||
try {
|
||||
packet.setAddress(InetAddress.getByName("239.255.255.250"));
|
||||
packet.setPort(1900);
|
||||
mSocket.send(packet);
|
||||
packet.setData(NOTIFY_MediaRenderer);
|
||||
mSocket.send(packet);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private Runnable listen_Runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
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();
|
||||
ProgressNOTIFY(data);
|
||||
} catch (IOException | XmlPullParserException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
handler.post(listen_thread);
|
||||
}
|
||||
};
|
||||
|
||||
public void ProgressNOTIFY(String data) throws IOException, XmlPullParserException {
|
||||
//Log.d(TAG, "ProgressNOTIFY: " + data);
|
||||
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() {
|
||||
@Override
|
||||
public void onSuccess(String str) {
|
||||
findDevice(finalLocation, str);
|
||||
}
|
||||
}, new JfClient.JJCallBack() {
|
||||
@Override
|
||||
public void onError(String str) {
|
||||
ShowToask(str);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void findDevice(String location, String xml) {
|
||||
DlnaDevice device;
|
||||
try {
|
||||
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) {
|
||||
int si = location.indexOf("/", 8);
|
||||
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("UDN", device.UDN);
|
||||
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);
|
||||
handler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (SAXException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user