乐趣区

关于harmonyos:优酷鸿蒙开发实践|多屏互动开发实践

作者:玉追 & 以绳

优酷与华为长期保持着良好的策略单干关系,旨在为消费者带来优质的影音娱乐体验。鸿蒙操作系统的流转个性为多屏互动带来了全新的玩法,本文以优酷播放核心的技术储备为切入点,联合鸿蒙零碎的镜像和流转个性,具体介绍了一般流转、自在视角和 zoom 等外围能力在鸿蒙上的实际之路。

背景介绍

鸿蒙分布式体验

华为定义的分布式体验次要蕴含连续性体验和协同体验两种。

连续性体验

当用户在一个设施上发动操作,并切换到另一个设施上持续操作时,用户可能马上在新的设施上持续以后的操作。连续性体验包含工作接续和音视频接续。

协同体验

多个设施上的软件和硬件能力互相协同,作为一个整体为用户提供比单设施更加高效、沉迷的体验。协同体验包含软件协同和硬件协同。

对于优酷而言,咱们曾经向用户提供了如下的多屏互动性能。

  • 用户用手机观看视频到某一个工夫点,而后切换到平板设施从方才的中断工夫点持续看视频
  • 用户用手机或者平板关上一个视频,而后应用投屏性能将视频投射到智慧屏或者电视盒子上,在大屏上持续观看
  • 用户在大屏上遇到登录或者领取等不方便使用大屏侧客户端实现的性能,他能够应用手机间接扫描大屏上的二维码登录或者领取。

上述性能,都是优酷客户端利用现有的“华为一碰传”,“华为 HiPlay”等性能能够间接实现的。咱们心愿借助鸿蒙 OS 提供的特色性能,实现若干以后优酷客户端所不具备的“新性能”,开发出若干“纯鸿蒙”专有个性,而后与 Android 优酷主客相交融。鸿蒙代码与 Android 代码互相联动,独特为消费者提供各种酷炫的影音娱乐性能。

优酷客户端横跨 Android,iOS,iPad,OTT 等多种软硬件平台,彼此之前能够通过投屏等性能互相联动,人造具备多屏互动的场景。

而 HarmonyOS 采纳了多种分布式技术,使得应用程序的开发实现与不同终端设备的状态差别无关。这可能让开发者聚焦下层业务逻辑,更加便捷、高效地开发利用。

在优酷鸿蒙版本中,咱们基于 HarmonyOS 提供的分布式总线能力,与优酷端既有的投屏性能相结合,开发出全新的 HarmonyOS 多屏互动 FA, 提供多台鸿蒙设施之间多屏互动的性能。

这个 FA 也是 100% 利用鸿蒙 API 编写的,用户能够通过优酷鸿蒙版的播放页“视频流转”按钮, 将手机端正在播放的视频流转到其它鸿蒙设施上 (鸿蒙智慧屏, 平板等), 并能够将手机作为遥控器对大屏设施进行播控管制。

不仅能对大屏的音量、快进快退、播放速度、清晰度、剧集进行管制,还能够旋转大屏上的自在视角视频的角度。

“基于 HarmonyOS 的多屏互动”与传统投屏的最大区别是,咱们是利用 HarmonyOS 提供的“设施 / 服务发现机制”来搜寻对端设施,应用 HarmonyOS 的“建设连贯”性能来建设设施之间的双向通信。

因为 HarmonyOSOS 的“设施 / 服务发现机制”“建设连贯”性能通过高度优化,咱们本人的应用体验是“HarmonyOS 多屏互动”相比传统 DLNA 或者 Miracast 镜像性能,设施发现快,连贯建设快,且连贯建设之后十分稳固,不容易断连。

而且,咱们能够通过此连贯进行高速的数据传输,间接从操控侧 streaming 视频到大屏端。

上面,咱们简略介绍下 HarmonyOS 的分布式总线能力是如何与优酷既有的投屏性能相结合的。

投屏业务概览

投屏技术在咱们日常生活和工作中失去了越来越多的利用,手机、平板、个人电脑等无线屏显和扩大性能也给家庭、企业会议、产品公布、近程培训带来了更加便捷、更加高效的模式改革。市场上相应的产品解决方案也是百花齐放,例如苹果公司的 Airplay 无线投屏解决方案、WiFi 联盟的 Miracast 无线投屏解决方案、谷歌公司的 ChromeCast 无线投屏解决方案、英特尔公司的 WIDI 无线投屏解决方案等,都在不同水平上推动了家庭和办公场合多屏互动产品的降级演变。

无线投屏技术和网络环境的改善其实曾经标记着高效智能时代的降临,人们能够应用手机上网、看电视、娱乐、办公,智能电视除了看电视外,更趋向于智慧屏、显示屏的概念。大家心愿能在电视上浏览信息、购物、玩游戏等等。人们更心愿在大屏上享受看电视的沉迷感。将来的发展趋势同样也很显著,市场微小的潜在需要是投屏技术的最大推动力,将会出现一个百花齐放的“盛景”。

作为国内互联网视频巨头之一,优酷在投屏业务场景积攒了丰盛的技术和产品教训,并获得了十分迅速的倒退;另外,优酷独有的播放能力,例如自在视角、zoom、AI 超分、帧享 4K 等,也给多屏互动场景提供了强有力的扩大空间。整体而言,不论是优酷的投屏业务还是播放能力,都为同华为的单干打下了松软的根底。

鸿蒙流转场景

HarmonyOS 是新一代的智能终端操作系统,为不同设施的智能化、互联与协同提供了对立的语言,并带来简洁、晦涩、间断、安全可靠的全场景交互体验。HarmonyOS 自诞生之初就以“万物互联”为使命,通过一套代码和外围的分布式技术,满足了不同平台上各种硬件的需要,买通了手机、平板、电脑、汽车和智能穿戴等多种设施,完满实现了不同设施之间的流转。能够说,“流转”是鸿蒙生态最为外围的个性之一。

随着智能时代的到来,流转无处不在,不论是车机上的双向管制,还是智能家居间的一触即连;不论是办公室的文件一碰投,还是手机和智慧屏的超级联结,有屏幕的中央就能实现流转。另一方面,5G 时代从新定义了公众的文化娱乐形式,更大的屏幕、更高的码率、更智能的流转成为了外围诉求,在这个背景下,鸿蒙跟优酷自然而然走到了一起。

优酷投屏能力幅员

优酷投屏能力不仅能笼罩传统的局域网协定,如 DLNA、AirPlay 等,还全新自研了云投屏协定,彻底突破了局域网组播的限度,进步了设施发现成功率。此外,为了减少全新玩法,最新的魔屏设施附赠了 NFC 贴纸,实现了一碰投性能,引入了全新的玩法。接下来具体介绍下优酷投屏的能力幅员。

能力幅员

无线投屏有三个最根本的因素:内容、设施和协定。其中,内容能够是非实时的数据文件,例如电影、图片、音乐等,也能够是实时的数据流,例如屏幕镜像、直播流等。设施包含发动投屏的内容提供方(简称“发送端”)和接管投屏的内容出现方(简称“接收端”),其中常见的发送端包含手机、平板等挪动设施,负责获取远端或本地存储的媒体资源,并传输给接收端;接收端则负责响应来自发送端的内容和播控指令,并实现后续的内容出现。协定则提供了发送端和接收端之间的交互规约,笼罩了包含设施发现、数据传输、播放管制等外围链路,比拟有代表性的协定包含局域网投屏场景的 SSDP 和 SOAP 协定、云投屏场景的 MTOP 和 ACCS 协定等。

多屏互动业务复杂度高,交互链路长,横跨大小屏两条业务线,波及到包含广告、会员、运营商、播放、硬件、媒资等十分多的业务方。

通过大量需要的长期打磨,优酷最终造成了如下的多屏互动幅员,能够分为投屏协定层,投屏播控层,业务适配层等外围组成部分:

投屏协定层

1、局域网投屏。包含 DLNA 和 AirPlay,通用性较强,但受限于组播能力,常会呈现发现不了设施的问题;

2、云投屏。云投屏是为了解决局域网协定无奈发现设施而自研的新协定,能无效晋升设施发现成功率,但受限于自营的大屏端利用,通用性受到了较大的限度;

3、NFC 投屏。作为魔屏新硬件宣推的新个性之一,NFC 投屏配合附带的贴纸,缩短了挪动端投屏的操作链路,实现了优酷视频的“一碰投”。

投屏播控层

  1. DRM 治理。负责投屏设施的治理和校验,保障版权视频的正确投放;
  2. 格局解决。适配和兼容不同的大屏设施,保障投屏后的播放体验;
  3. 清晰度治理。负责多路清晰度的自适应和异样降级,兼顾广告等业务场景;
  4. 辅助调度。基于投屏的专属域名,具备针对不同区域、运营商、设施信息的动静流治理和调度能力。

业务适配层

  1. 投屏广告。包含内投内、内投外、外投内三种组合。此外,大小屏端上投屏广告的投放零碎也在开发中;
  2. 点直短交融。将点播、直播、短视频三个场景的播放适配模块下沉至投屏外部保护,这对于前期监控链路的对立和投屏能力的外发,都有重要意义。

鸿蒙零碎初实际

一般流转

“鸿蒙流转”指利用了鸿蒙操作系统个性的多屏互动形式,与传统投屏协定最大的区别在于对鸿蒙操作系统的依赖。具体而言,鸿蒙操作系统不仅提供了“设施 / 服务发现机制”作为设施发现的协定,还提供了“设施连贯能力”反对设施之间进行双向通信。

相似传统的投屏协定,鸿蒙流转包含基于 URL 的一般流转和基于流传输的流转。一般流转是指基于鸿蒙传输能力的多屏互动形式,不同于 DLNA 等通用协定,鸿蒙提供了包含设施发现、数据传输、利用查问、文件分享等外围能力,不仅能提供较原生协定而言更稳固的连贯,还能依照业务诉求,将自研的 APK(例如酷喵)通过小屏传输至大屏并唤起,实现一系列定制化操作。

先围绕一般流转进行介绍,其时序图如下所示。

如上图所示,对其中局部外围流程的实现进行简略介绍。

鸿蒙设施发现

跟 DLNA 投屏和云投屏发现流程完全一致,鸿蒙的发现协定在 DlnaDevs 的 search 办法中实现:

// 鸿蒙 search
    if (HarmonyCastMgr.haveInst()) {HarmonyCastMgr.getInst().searchDevs();
        // 自在视角 search
        if (HarmonyCastMgr.getInst().hasMirr()){HarmonyCastMgr.getInst().searchHarmonyMirrorDevs();}
    }

再来看看鸿蒙发现流程的实现细节:

    // 搜寻设施(异步形式)public boolean searchDevs() {
        boolean ret = false;
        if (isHarmonyEnable()) {Intent intent = new Intent();
            ComponentName componentName = new ComponentName(PackageContant.PACKAGE_YOUKU, "com.youku.feature.MiddlewareAbility");
            intent.setComponent(componentName);
            intent.putExtra(AbilityUtils.PARAM_KEY_INSTALL_ON_DEMAND, true);
            intent.setAction("action.videoplayer.getdevicelist");
            try {mActivity = YoukuContext.getTopActivity();
                ret = AbilityUtils.connectAbility(mActivity, intent, mServiceConnection);
            } catch (RuntimeException e) {e.printStackTrace();
                ret = false;
            }
        }
        return ret;
    }

鸿蒙发现协定通过 AIDL 依赖了 FA 的通道,其中 mServiceConnection 外部对 IBinder 对象进行了解析,映射为多屏互动定义的 Device 类型,并回调设施列表的更新接口,外围实现如下:

   public ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {LogEx.d(tag(), "onServiceConnected");
            HarmonyRCS rcs = new HarmonyRCS(service);
            String[] devices = null;

            try {devices = rcs.getDeviceList();
            } catch (RemoteException e) {e.printStackTrace();
            }

            // 设施 ID 和名称数组,以适应鸿蒙 AIDL 查问格局
            List<String> deviceIdList = new ArrayList<>();
            List<String> deviceNameList = new ArrayList<>();

            for (int i = 0; i < devices.length; i++) {if ((i & 1) == 0) {deviceIdList.add(devices[i]);
                } else {deviceNameList.add(devices[i]);
                }
            }

            // 原始数据映射为 Client 格局
            if (deviceNameList.size() >= deviceIdList.size()) {mHarmonyDevs.clear();
                for (int i = 0; i < deviceIdList.size(); i++) {String deviceId = deviceIdList.get(i);
                    String deviceName = deviceNameList.get(i);
                    if (StringUtils.isNotBlank(deviceId) && StringUtils.isNotBlank(deviceName)) {Client client = new Client();
                        
                        ...

                        mHarmonyDevs.put(deviceId, client);
                    }
                }

                // 判断大屏设施是否在线,如果不在线,则进行投屏
                if (DlnaApiBu.api().proj().stat() == DlnaPublic.DlnaProjStat.PLAYING) {Client currentDev = DlnaApiBu.api().proj().req().mDev;
                    if (currentDev != null && currentDev.isHarmonyDev() && !mHarmonyDevs.containsKey(currentDev.getDeviceUuid())) {stopProjEx();
                    }
                }

                // 回调调用方获取设施列表
                if (null != mRcsCallback) {mRcsCallback.onHarmonyDevsChanged();
                }
            }

            try {if (mActivity != null) {AbilityUtils.disconnectAbility(mActivity, mServiceConnection);
                }
            } catch (Exception pE) {pE.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {LogEx.d(tag(), "onServiceConnected");
        }
    };

抉择设施并启动 FA

相似云投屏自研协定,鸿蒙一般流转依赖独自的发现流程,相似于其余协定,创立 HarmonyCastTrunkBiz 以作为鸿蒙协定治理类,并实现了如下根底接口:

    // 开始投屏
    void start();
  
    // 进行投屏
    void stop();

    // 发送播放指令
    void play();

    // 发送暂停指令
    void pause();

    // 发送 seek 指令
    void seek(int prog);

    // 发送设置音量指令
    void setVolume(int volume);

因为鸿蒙 FA 提供了定制的遥控器界面和双向数据传输通道,因而所有发送指令的工作均由鸿蒙 FA 接管,上述负责发送指令的接口仅仅同步了小屏端的播放状态。用户点击选中鸿蒙设施后,触发 start 办法并启动鸿蒙协定入口,由 HarmonyCastMgr 的 startHarmony 负责同鸿蒙 FA 之间的数据交互:

    // 投屏所需的播放数据
    HarmonyCastData castData = new HarmonyCastData();
    castData.mDev = req.mDev;
    castData.mUrl = req.mUrl;
    castData.metaData = DlnaMetadata.getInst().getMetadataWithReq(req);
    castData.isFromNowbar = isFromNowbar;

    // FA 遥控器所需的 UI 数据
    HarmonyParameterBean parameterBean = new HarmonyParameterBean();
    parameterBean.deviceUuid = req.mDev.getDeviceUuid();
    parameterBean.mShowTitle = req.mShowTitle;
    parameterBean.projSource = "";
    parameterBean.isYoukuApp = req.mDev.isYoukuApp;
    String parameterData = JSON.toJSONString(parameterBean);
    
    // 按 FA 数据格式进行封装
    String touchuanData = JSON.toJSONString(castData);
    HarmonyPaBean paBean = new HarmonyPaBean();
    paBean.touchuanData = touchuanData;
    paBean.parameterData = parameterData;
  
    final String harmonyJson = JSON.toJSONString(paBean);
    Activity activity = YoukuContext.getTopActivity();
    Intent jIntent = new Intent();
    ComponentName component = new ComponentName(PackageContant.PACKAGE_YOUKU, "com.youku.feature.MainAbility");
    jIntent.putExtra(AbilityUtils.PARAM_KEY_INSTALL_ON_DEMAND, true);
    jIntent.putExtra("harmonyJson", harmonyJson);
    jIntent.setComponent(component);

    try {
        // 每次开始投屏前检测一次远端是否在线,防止因大屏掉线导致的投屏失败
        boolean remoteValid = true;
        if (HarmonyCastMgr.haveInst()) {remoteValid = HarmonyCastMgr.getInst().searchDevs();}

        if (remoteValid) {AbilityUtils.startAbility(activity, jIntent);
        } else {stopProjEx();
        }
    } catch (Exception e) {e.printStackTrace();
    }

自在视角

自在视角由阿里娱乐摩酷实验室研发,是一种能够随便滑动视频、自在切换观看视角的播放技术。自在视角视频是多视角直播的进一步倒退,带给用户更多的主动性。用户能够在观看球赛时旋转视角,并放大部分画面,近距离观看偶像球员的灌篮动作,实现堪比跨次元的实在观影体验。

以下是“这就是街舞”综艺的自在视角成果:

视频请见原文中:优酷鸿蒙开发实际|多屏互动开发实际

不同于一般视频,自在视角视频的码率广泛偏高。例如上述街舞录制现场,总共装置了超过 40 台专用相机,造成的阵列采集画面全方位记录了每个精彩霎时,并实现毫秒级同步和近程协同管制,采集到的画面通过焦点改正和 3D 重建,再基于各机位采集到的纹理、深度、姿势等参数信息,最终将多角度扩散的画面拼接成一个高达 6K、8K 的高清视频文件。

因而,自在视角视频在晋升用户观感的同时,也对播放端的网络环境和解码性能提出了十分高的要求。最后的自在视角实现计划是基于流转个性,小屏端将自在视角视频的 M3U8 地址或播控指令,通过上述流转能力传递给大屏侧,由大屏侧实现数据的下载、解码和渲染等后续流程。但思考到华为智慧屏的硬件性能不足以撑持这种规模的计算量,传统的流转计划不得不被叫停。

为此,开发团队比照了鸿蒙零碎上现存的所有投屏协定,失去如下表的论断:

鸿蒙投屏协定 长处 毛病
DLNA 规范成熟协定,通用性强 原生扩大能力较弱
云投屏 不依赖局域网,扩展性强 通用性较差
鸿蒙协定 零碎适配度高,扩大能力强 依赖鸿蒙零碎
Cast+ 协定 零碎适配度高,兼容性强,满足流传输须要 依赖华为生态

通过外部评估以及同华为研发团队的探讨,开发团队最终决定放弃传统的基于 URL 的投屏形式,采纳基于华为 Cast+ 的镜像投屏计划,具体而言,是在手机端失常播放和操控自在视角视频,并把播放器视图通过 Cast+ 镜像到电视端。

简略介绍下华为 Cast+ 协定的实现细节。如下图所示,华为 Cast+ Kit 是华为自研的、以手机为核心的多屏协同组件,业务方可据此实现多设施之间疾速、稳固、低时延的镜像传输。

基于华为 Cast+ 协定,自在视角场景的投屏链路跟一般投屏协定大体保持一致,重叠的局部包含设施搜寻、抉择设施和建连,不同之处在于,自在视角视频最初一步并没有投放播放地址到大屏,而是创立虚构屏并实现显示,虚构屏的创立机会和形式是实际过程中的重中之重。

自在视角流转计划的实质,能够概括为两个方面:首先,将遥控器页面作为主屏幕,买通其与播放页之间的双向数据通道,以实现播放管制和状态同步;其次,在虚构屏上启动播放相干的视图,作为镜像和传输到大屏的内容。

主屏幕的计划根本确定,轮到虚构屏的时候却踩了坑。最后能想到的虚构屏渲染对象,自然而然是全屏播放页,然而试了才发现,间接将全屏播放页渲染到虚构屏,会存在如下两个问题,附带剖析报告如下:

问题 1:主屏幕上的遥控器页面首先被镜像到大屏。

  • 起因:Cast+ 会在建连胜利后、设施处于 PLAYING 状态时,开始抓取虚构屏的内容,如果虚构屏尚未加载,会截取主屏幕内容作为兜底。通过测试,这个时间差大略在 100ms 左右,而期间播放页无奈实现初始化,因而会存在主屏幕内容占用的问题。

问题 2:播放页进入后存在横竖屏切换逻辑,导致镜像后屏幕会经验一次转屏。

  • 起因:属于播放页自适应逻辑,初始进入时为竖屏,在镜像后会触发横屏切换逻辑,从而导致大屏侧的转屏。

外部综合评估后,决定采纳更加轻量的形式实现虚构屏。咱们发现,播放器 Dialog 中只蕴含 SurfaceView 和 Loading 状态等内容,如果仅仅镜像 Dialog 级别,尽管减少了较多的播放器解决逻辑,但保障了上屏速度和更快的响应效率。调整后的计划构造如下图所示。

该计划具备如下劣势:

  1. 优化了播放器的生命周期,每次在自在视角流转和小屏播放之间切换时,仅仅切换 SurfaceView,并不重建播放器,此时播放器只是处于 STOPPED 状态,切到小屏播放后,跳过了初始化和播放地址申请等过程,保障疾速起播;
  2. 将启动 Presentation 的机会提前,在收到 onDisplayAdded 时就进行页面启动和播放器续播,大大缩短了上屏工夫。

综上所示,最终的成果如下视频所示。

视频请见原文中:优酷鸿蒙开发实际|多屏互动开发实际

线上体现

网友们对鸿蒙零碎的个性和优酷鸿蒙版本的体现,也体现出了强烈的趣味,咱们摘取了网上的一些体验视频,列举如下:

  • 《优酷鸿蒙版体验——转自知乎》:https://www.bilibili.com/vide…
  • 《鸿蒙优酷投屏 爱了爱了》:https://www.bilibili.com/s/vi…

随后,通过两个版本的继续迭代,优酷鸿蒙版的稳定性和体验失去了极大改善。另一方面,随同着鸿蒙零碎的自我完善,优酷鸿蒙版的二期需要版本曾经开始排期,置信在单方强强联合之下,会继续给市场和用户带来惊喜。

总结

在优酷鸿蒙版多屏互动专项的开发过程中,各参与方在鸿蒙接口和调试环境尚不欠缺的时候染指,克服了重重困难,一直摸索试错,在极短的工夫内把握了鸿蒙开发技术栈,不仅顺利完成了大大小小的开发工作,还反馈给华为技术团队不少遗留问题和改良倡议。这是单方再一次的深度单干,也是一次十分胜利的实际。

对于华为而言,优酷鸿蒙版不仅给鸿蒙生态带来了开创性的视频新交互模式,让新用户大呼过瘾;而且完满适配了鸿蒙零碎流转个性、为后续更丰盛的新玩法铺平了路线。对于优酷而言,鸿蒙上的多屏互动实际,大大扩大了现有的多屏互动能力幅员,为鸿蒙新时代积攒了重要教训。

关注咱们,每周 3 篇挪动技术实际 & 干货给你思考!

退出移动版