DLNA源码分析之render启动

本文详细描述了Android设备如何使用UPnP协议进行服务注册、创建render设备启动流程,包括初始化Router、创建本地设备并在局域网中注册,以便于通过多播接收器进行设备搜索和指令传递。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1,概述

2,render设备启动流程

2.1  AndroidUpnpServiceImpl类

2.2 创建router

2.3  创建本地设备并注册


1,概述

        DLNA设备、服务的注册及发现(依赖开源库cling),DLNA中设备的注册、发现主要基于UPNP协议实现,这是微软推行的一个标准。Upnp最大的愿景是希望任何设备只要一接入网络,所有网上的设备马上就能知道有新设备加入,这些设备之间就可以彼此通信。

2,render设备启动流程

2.1  AndroidUpnpServiceImpl类

        AndroidUpnpServiceImpl类声明如下:

/**
 * Provides a UPnP stack with Android configuration as an application service component.
 * <p>
 * Sends a search for all UPnP devices on instantiation. See the
 * {@link AndroidUpnpService} interface for a usage example.
 * </p>
 * <p/>
 * Override the {@link #createRouter(UpnpServiceConfiguration, ProtocolFactory, Context)}
 * and {@link #createConfiguration()} methods to customize the service.
 *
 * @author Christian Bauer
 */
public class AndroidUpnpServiceImpl extends Service {

    ......

}

提供一个UPnP协议栈,通过android service暴漏服务。我们创建render时候,只需要继承该service便可。

2.2 创建router

         在AndroidUpnpServiceImpl类中,创建UpnpService服务,

    public void onCreate() {
        super.onCreate();

        upnpService = new UpnpServiceImpl(createConfiguration()) {

            @Override
            protected Router createRouter(ProtocolFactory protocolFactory, Registry registry) {
                return AndroidUpnpServiceImpl.this.createRouter(
                    getConfiguration(),
                    protocolFactory,
                    AndroidUpnpServiceImpl.this
                );
            }

            @Override
            public synchronized void shutdown() {
                // First have to remove the receiver, so Android won't complain about it leaking
                // when the main UI thread exits.
                ((AndroidRouter)getRouter()).unregisterBroadcastReceiver();

                // Now we can concurrently run the Cling shutdown code, without occupying the
                // Android main UI thread. This will complete probably after the main UI thread
                // is done.
                super.shutdown(true);
            }
        };
    }

走到RouterImpl#enable(),

    public boolean enable() throws RouterException {
        lock(writeLock);
        try {
            if (!enabled) {
                try {
                    log.fine("Starting networking services...");
                    networkAddressFactory = getConfiguration().createNetworkAddressFactory();

                    startInterfaceBasedTransports(networkAddressFactory.getNetworkInterfaces());
                    startAddressBasedTransports(networkAddressFactory.getBindAddresses());

                    // The transports possibly removed some unusable network interfaces/addresses
                    if (!networkAddressFactory.hasUsableNetwork()) {
                        throw new NoNetworkException(
                            "No usable network interface and/or addresses available, check the log for errors."
                        );
                    }

                    // Start the HTTP client last, we don't even have to try if there is no network
                    streamClient = getConfiguration().createStreamClient();

                    enabled = true;
                    return true;
                } catch (InitializationException ex) {
                    handleStartFailure(ex);
                }
            }
            return false;
        } finally {
            unlock(writeLock);
        }
    }

        完成了多播接收器multicastReceiver初始化和HTTP servers的创建,通过startInterfaceBasedTransports和startAddressBasedTransports完成了本地局域网的组网。

2.3  创建本地设备并注册

        在AndroidUpnpServiceImpl继承类的onCreate()方法中,创建本地设备并注册,

    override fun onCreate() {
        logger.i("DLNARendererService create.")
        super.onCreate()
        avTransportControl = AVTransportController(applicationContext)
        audioControl = AudioRenderController(applicationContext)
        try {
            localDevice = createRendererDevice(Utils.getHttpBaseUrl(applicationContext))
            upnpService.registry.addDevice(localDevice)
        } catch (e: Exception) {
            e.printStackTrace()
            stopSelf()
        }
    }

        至此,完成了render局域网组网和本地设备的注册(设备信息注册到239.255.255.250)。打开control pointer设备(如爱奇艺),点击投屏按钮,就能从组播239.255.255.250那里搜索到render设备信息,为下一步指令交付建立通道。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

佳哥的技术分享

创作不易,谢谢鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值