最近做DLNA音乐播放的功能,由于相关资料相对较少,官网上的英文文档又比较难理解,导致实现这一功能花费了大量时间。今天把我的Demo分享给大家。
效果图如下:
1,本Demo实现了DMR设备的搜索,注册事件监听,获取播放信息,音量,播放暂停,进度更新等功能
2,引入cling-core-1.0.5库,主要实现了DMC的功能
3,主要逻辑:
- 启动一个简单的Http服务器,给所有请求返回字节流文件,请求可以携带参数来指定从文件的那个地方开始下载,从而实现快进功能
- 在应用启动时,会搜索局域网内的DMR设备,当搜索到后,将第一个设备设置为默认播放设备
- 点击播放时,建立与播放器的"AVTransport"的服务,给它传送播放的URI地址,然后调用播放指令
关键代码如下:
一、DMC控制部分
<span style="font-size:18px;">public class ActionController {
private static final UDAServiceType AV_TRANSPORT_TYPE = new UDAServiceType("AVTransport");
private static final UDAServiceType RENDERING_CONTROL_TYPE = new UDAServiceType("RenderingControl");
public void play(Device device, String path, final ControllerListener callback){
final Service service = device.findService(AV_TRANSPORT_TYPE);
if (service == null) return;
ActionCallback actionCallback = new SetAVTransportURI(service, path) {
@Override
public void failure(ActionInvocation paramActionInvocation, UpnpResponse paramUpnpResponse, String paramString) {
// Current state of service prevents invoking that action. Connection error or no response received.
Log.w("Dlna", "--- SetAVTransportURI failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, "SetAVTransportURI " + paramString);
}
@Override
public void success(ActionInvocation invocation)
{
super.success(invocation);
ActionCallback palyCallback = new Play(service, "1") {
@Override
public void failure(ActionInvocation paramActionInvocation,
UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "--- Play failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, "failure " + paramString);
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "--- Play success()");
if(callback != null) callback.onSuccess(invocation);
super.success(invocation);
}
};
execute(palyCallback);
}
};
execute(actionCallback);//URL
}
public void stop(Device device, final ControllerListener callback)
{
Service service = device.findService(AV_TRANSPORT_TYPE);
if (null == service) return;
ActionCallback actionCallback = new Stop(service) {
@Override
public void failure(ActionInvocation paramActionInvocation,
UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "stop() ActionCallback failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, paramString);
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "stop() ActionCallback success()");
if(callback != null) callback.onSuccess(invocation);
super.success(invocation);
}
};
execute(actionCallback);
}
public void pause(Device device, final ControllerListener callback)
{
Service service = device.findService(AV_TRANSPORT_TYPE);
if (service == null) return;
ActionCallback pauseCallback = new Pause(service) {
@Override
public void failure(ActionInvocation paramActionInvocation, UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "pause() ActionCallback failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, paramString);
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "pause() ActionCallback success()");
if(callback != null) callback.onSuccess(invocation);
super.success(invocation);
}
};
execute(pauseCallback);
}
public void resume(DmrDevice device, final ControllerListener callback) {
Service<?, ?> dlnaService = device.findService(AV_TRANSPORT_TYPE);
if (dlnaService == null) return;
ActionCallback playCallback = new Play(dlnaService) {
@Override
public void failure(ActionInvocation paramActionInvocation, UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "Play() ActionCallback failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, paramString);
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "Play() ActionCallback success()");
if(callback != null) callback.onSuccess(invocation);
super.success(invocation);
}
};
execute(playCallback);
}
public void seek(DmrDevice device, long millisecond, final ControllerListener callback) {
Service<?, ?> dlnaService = device.findService(AV_TRANSPORT_TYPE);
if (dlnaService == null) return;
String dateTime = Utils.parseMillisecond(millisecond);
Log.i("Dlna", "seek dateTime = " + dateTime);
ActionCallback seekCallback = new Seek(dlnaService, dateTime) {
@Override
public void failure(ActionInvocation paramActionInvocation, UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "Seek() ActionCallback failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, paramString);
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "Seek() ActionCallback success()");
if(callback != null) callback.onSuccess(invocation);
super.success(invocation);
}
};
execute(seekCallback);
}
public void setMute(DmrDevice device, boolean desiredMute, final ControllerListener callback) {
Service<?, ?> dlnaService = device.findService(RENDERING_CONTROL_TYPE);
if (dlnaService == null) return;
ActionCallback setMuteCallback = new SetMute(dlnaService, desiredMute) {
@Override
public void failure(ActionInvocation paramActionInvocation, UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "SetMute() ActionCallback failure() paramString = " + paramString);
if(callback != null){
callback.onExecuted();
callback.onFailare(paramActionInvocation, paramUpnpResponse, paramString);
}
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "SetMute() ActionCallback success()");
if(callback != null){
callback.onExecuted();
callback.onSuccess(invocation);
}
super.success(invocation);
}
};
execute(setMuteCallback);
}
public void getMute(DmrDevice device, final ControllerListener callback) {
Service<?, ?> dlnaService = device.findService(RENDERING_CONTROL_TYPE);
if (dlnaService == null) return;
ActionCallback getMuteCallback = new GetMute(dlnaService) {
@Override
public void failure(ActionInvocation paramActionInvocation, UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "GetMute() ActionCallback failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, paramString);
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "GetMute() ActionCallback success()");
if(callback != null) callback.onSuccess(invocation);
super.success(invocation);
}
@Override
public void received(ActionInvocation invocation, boolean isMute) {
Log.i("Dlna", "GetMute() ActionCallback received() isMute = " + isMute);
if(callback != null) callback.onReceived(invocation, isMute);
}
};
execute(getMuteCallback);
}
public void setVolume(DmrDevice device, long volume, final ControllerListener callback) {
Service<?, ?> dlnaService = device.findService(RENDERING_CONTROL_TYPE);
if (dlnaService == null) return;
ActionCallback setVolumeCallback = new SetVolume(dlnaService, volume) {
@Override
public void failure(ActionInvocation paramActionInvocation, UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "SetVolume() ActionCallback failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, paramString);
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "SetVolume() ActionCallback success()");
if(callback != null) callback.onSuccess(invocation);
super.success(invocation);
}
};
execute(setVolumeCallback);
}
public void getVolume(DmrDevice device, final ControllerListener callback) {
Service<?, ?> dlnaService = device.findService(RENDERING_CONTROL_TYPE);
if (dlnaService == null) return;
ActionCallback getVolumeCallback = new GetVolume(dlnaService) {
@Override
public void failure(ActionInvocation paramActionInvocation, UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "GetVolume() ActionCallback failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, paramString);
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "GetVolume() ActionCallback success()");
if(callback != null) callback.onSuccess(invocation);
super.success(invocation);
}
@Override
public void received(ActionInvocation invocation, int volume) {
Log.i("Dlna", "GetVolume() ActionCallback received() volume = " + volume);
if(callback != null) callback.onReceived(invocation, volume);
}
};
execute(getVolumeCallback);
}
public void getTransportStatus(DmrDevice device, final ControllerListener callback) {
Service<?, ?> dlnaService = device.findService(AV_TRANSPORT_TYPE);
if (dlnaService == null) return;
ActionCallback actionCallback = new GetTransportInfo(dlnaService) {
@Override
public void failure(ActionInvocation paramActionInvocation, UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "GetTransportInfo() ActionCallback failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, paramString);
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "GetTransportInfo() ActionCallback success()");
if(callback != null) callback.onSuccess(invocation);
super.success(invocation);
}
@Override
public void received(ActionInvocation invocation, TransportInfo info) {
Log.i("Dlna", "GetTransportInfo() ActionCallback received() speed = " + info.getCurrentSpeed()
+ " transportState = " + info.getCurrentTransportState().getValue()
+ " transportStatus = " + info.getCurrentTransportStatus().getValue() );
if(callback != null) callback.onReceived(invocation, info);
}
};
execute(actionCallback);
}
public void getMediaInfo(DmrDevice device, final ControllerListener callback) {
Service<?, ?> dlnaService = device.findService(AV_TRANSPORT_TYPE);
if (dlnaService == null) return;
ActionCallback actionCallback = new GetMediaInfo(dlnaService) {
@Override
public void failure(ActionInvocation paramActionInvocation, UpnpResponse paramUpnpResponse, String paramString) {
Log.w("Dlna", "getMediaInfo() ActionCallback failure() paramString = " + paramString);
if(callback != null) callback.onFailare(paramActionInvocation, paramUpnpResponse, paramString);
}
@Override
public void success(ActionInvocation invocation) {
Log.i("Dlna", "getMediaInfo() ActionCallback success()");
if(callback != null) callback.onSuccess(invocation);
super.success(invocation);
}
@Override
public void received(ActionInvocation invocation, MediaInfo info) {
Log.i("Dlna", "getMediaInfo() ActionCallback received() getCurrentURI = " + info.getCurrentURI()
+ " getCurrentURIMetaData = " + info.getCurrentURIMetaData()
+ " getNextURI = " + info.getNextURI()
+ " getNextURIMetaData = " + info.getNextURIMetaData()
+ " getWriteStatus = " + info.getWriteStatus().toString()
+ " getMediaDuration = " + info.getMediaDuration() );
if(callback != null) callback.onReceived(invocation, info);
}
};
execute(actionCallback);
}
public void execProgress(Device<?, ?, ?> device, ProgressListener callback) {
Service<?, ?> dlnaService = device.findService(AV_TRANSPORT_TYPE);
if (dlnaService == null) return;
ActionCallback actionCallback = new MusicProgress(dlnaService, callback);
startTimer(actionCallback);
}
public void getProgress(Device<?, ?, ?> device, ProgressListener callback) {
Service<?, ?> dlnaService = device.findService(AV_TRANSPORT_TYPE);
if (dlnaService == null) return;
ActionCallback actionCallback = new MusicProgress(dlnaService, callback);
execute(actionCallback);
}
private AVTransportSubcriptCallBack mAVTransportSubscriptionCallback;
public void initSubscriptCallback(Device<?, ?, ?> device, Handler handler) {
Service<?, ?> dlnaService = device.findService(AV_TRANSPORT_TYPE);
if (dlnaService == null) return;
mAVTransportSubscriptionCallback = new AVTransportSubcriptCallBack(dlnaService, handler);
MainActivity.upnpService.getControlPoint().execute(mAVTransportSubscriptionCallback);
}
public void endSubscriptCallback(){
Log.i("Dlna", "ActionController endSubscriptCallback()...");
if (mAVTransportSubscriptionCallback != null) {
mAVTransportSubscriptionCallback.end();
mAVTransportSubscriptionCallback = null;
}
}
}</span>
<span style="font-size:18px;">// AndroidUpnpService绑定后的监听,绑定成功或失败后的处理
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
Log.i(TAG, "ServiceConnection onServiceConnected()...");
upnpService = (AndroidUpnpService) service;
isServiceConnected = true;
searchDMR();
}
public void onServiceDisconnected(ComponentName className) {
upnpService = null;
}
};
// 搜索DMR设备
private void searchDMR() {
dmrDeviceManager.removeAllDevices();
dmrDeviceManager.searchDmrDevices(new OnSearchDmrDeviceListener() {
@Override
public void onDeviceRemove(final DmrDevice device) {
Log.i(TAG, "dmrDeviceManager.searchDmrDevices() onDeviceRemove " + device.getName());
dmrDevicesList.remove(device);
}
@Override
public void onDeviceAdd(final DmrDevice device) {
Log.i(TAG, "dmrDeviceManager.searchDmrDevices() onDeviceAdd " + device.getName());
dmrDevicesList.add(device);
// 判断第一次,初始化设置一个设备
if(curDmrDevice == null){
setCurDmrDevice(dmrDevicesList.get(0));
runOnUiThread(new Runnable() {
@Override
public void run() {
btRender.setText("Render ( " + curDmrDevice.getName() + " ) ");
}
});
}
}
});
}</span>
Demo下载地址:http://download.csdn.net/detail/u010134293/9224871