投屏功能

备注: 新增Support包 Suppot包中包含投屏功能,不需要的可以删掉,uilibs中注释掉投屏相关代码即可;

功能描述

投屏是基于DLNA功能实现的, 使用的ClingDLNA类库 , 确保使用的机器是具备DLNA功能的手机 理论上支持API16以上的机型, 实际测试有部分API 16以上的机型不支持

DLNA 协议中包含多项协议及标准, 其中UPnP协议是最重要的部分 UPnP协议定义了设备之间,设备和控制点,控制点之间通信的协议

投屏依赖配置

maven {
            url 'http://4thline.org/m2'
        }
	api 'org.eclipse.jetty:jetty-server:8.1.8.v20121106'
    api 'org.eclipse.jetty:jetty-servlet:8.1.8.v20121106'
    api 'org.eclipse.jetty:jetty-client:8.1.8.v20121106'
    api 'org.fourthline.cling:cling-core:2.1.1'
    api 'org.fourthline.cling:cling-support:2.1.1'

设备注册监听实现

    private BrowseRegistryListener registryListener = new BrowseRegistryListener();

private DevicePopu devicePopu;//demo层展示投屏操作的pop
protected class BrowseRegistryListener extends DefaultRegistryListener {

        @Override
        public void remoteDeviceDiscoveryStarted(Registry registry, RemoteDevice device) {
//            deviceAdded(device);
        }

        @Override
        public void remoteDeviceDiscoveryFailed(Registry registry, final RemoteDevice device, final Exception ex) {
//            deviceRemoved(device);
        }
        /* End of optimization, you can remove the whole block if your Android handset is fast (>= 600 Mhz) */

        @Override
        public void remoteDeviceAdded(Registry registry, RemoteDevice device) {
            if (device.getType().getNamespace().equals("schemas-upnp-org") && device.getType().getType().equals("MediaRenderer")) {
                deviceAdded(device);
            }

        }

        @Override
        public void remoteDeviceRemoved(Registry registry, RemoteDevice device) {
            deviceRemoved(device);
        }

        @Override
        public void localDeviceAdded(Registry registry, LocalDevice device) {
//            deviceAdded(device);
        }

        @Override
        public void localDeviceRemoved(Registry registry, LocalDevice device) {
//            deviceRemoved(device);
        }

        public void deviceAdded(final Device device) {
            runOnUiThread(new Runnable() {
                public void run() {
                    if (devicePopu == null) {
                        devicePopu = new DevicePopu(WatchActivity.this);
                        devicePopu.setOnItemClickListener(new OnItemClick());
                    }
                    devicePopu.deviceAdded(device);
                }
            });
        }

        public void deviceRemoved(final Device device) {
            runOnUiThread(new Runnable() {
                public void run() {
                    if (devicePopu == null) {
                        devicePopu = new DevicePopu(WatchActivity.this);
                        devicePopu.setOnItemClickListener(new OnItemClick());
                    }
                    devicePopu.deviceRemoved(device);
                }
            });
        }
    }

服务连接监听实现

private AndroidUpnpService upnpService;
private ServiceConnection serviceConnection = new ServiceConnection() {

        public void onServiceConnected(ComponentName className, IBinder service) {
            Log.e("Service ", "mUpnpServiceConnection onServiceConnected");
            upnpService = (AndroidUpnpService) service;
            // Clear the list
            if (devicePopu != null)
                devicePopu.clear();
            // Get ready for future device advertisements
            upnpService.getRegistry().addListener(registryListener);
            // Now add all devices to the list we already know about
            for (Device device : upnpService.getRegistry().getDevices()) {
                registryListener.deviceAdded(device);
            }
            // Search asynchronously for all devices, they will respond soon
            upnpService.getControlPoint().search(); // 搜索设备
        }

        public void onServiceDisconnected(ComponentName className) {
            upnpService = null;
        }
    };

绑定AndroidUpnpService 服务

bindService(
                new Intent(this, AndroidUpnpServiceImpl.class),
                serviceConnection,
                Context.BIND_AUTO_CREATE
        )

离开页面时一定要注销服务及监听,避免内存泄漏

if (upnpService != null) {
            upnpService.getRegistry().removeListener(registryListener);
        }
        this.unbindService(serviceConnection);

获取支持投屏的设备

/**
     * 获取支持投屏的设备
     *
     * @return 设备列表
     */
    @Nullable
    public Collection<Device> getDmrDevices() {
        if (upnpService == null)
            return null;
        Collection<Device> devices = upnpService.getRegistry().getDevices(DMR_DEVICE_TYPE);
        return devices;
    }

实例化投屏控制对象

    /**
     * 
     * @param paramDeviceItem  投屏设备
     * @param paramAndroidUpnpService 通信服务
     * @param paramString1 资源地址
     * @param webinarInfo 房间信息
     */
        DMCControl dmcControl = new DMCControl(deviceDisplay, service, mPlayer.getOriginalUrl(), webinarInfo);

设置投屏控制回调

   public void setDMCControlListener(DMCControlListener controlListener) {}

回调说明

public interface DMCControlListener {
   int ERROR_PLAY = 50001;
   int ERROR_PAUSE = 50002;
   int ERROR_STOP = 50003;
   int ERROR_GET_POSITION = 50004;
   int ERROR_SEEK = 50005;
   int ERROR_PERMISSION = 50006;

   String ERROR_MSG_PERMISSION="无投屏权限,如需使用请咨询您的销售人员或拨打客服电话:400-888-9970";

   void onStart();//投屏开始

   void onPause();//暂停投屏

   void onStop();//停止投屏

   void currentPosition(String curTIme, String duration);//播放进度

   void onError(int errorCode, String errorMsg);//错误回调
}

开始播放(投屏)

public void play() {}

暂停播放

 public void pause() {}

重播

public void rePlayControl() {}

停止播放(停止投屏)

public void stop() {}

设置进度

 public void seekToPosition(String target) {}