最近做DLNA音樂播放的功能,由於相關資料相對較少,官網上的英文文檔又比較難理解,導致實現這一功能花費了大量時間。今天把我的Demo分享給大家。
效果圖如下:
1,本Demo實現了DMR設備的搜索,註冊事件監聽,獲取播放信息,音量,播放暫停,進度更新等功能
2,引入cling-core-1.0.5庫,主要實現了DMC的功能
3,主要邏輯:
- 啓動一個簡單的Http服務器,給所有請求返回字節流文件,請求可以攜帶參數來指定從文件的那個地方開始下載,從而實現快進功能
- 在應用啓動時,會搜索局域網內的DMR設備,當搜索到後,將第一個設備設置爲默認播放設備
- 點擊播放時,建立與播放器的"AVTransport"的服務,給它傳送播放的URI地址,然後調用播放指令
<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