1.增强axmol引擎视频播放之 - Linux(Ubuntu)视频播放支持
2.unimrcpclient源码分析mrcp components
3.è°è°MediaStream
增强axmol引擎视频播放之 - Linux(Ubuntu)视频播放支持
本文探讨在著名的Linux发行版Ubuntu支持视频渲染到纹理播放的实现过程,重点介绍如何集成libvlc以增强axmol引擎在Linux平台上的视频播放功能。在完成对Android平台的视频纹理渲染支持后,考虑到axmol引擎支持的平台包括macos、windows、ios/tvos、jdk 1.7 源码android、linux,Linux平台的缺失成为待补之项。
深入研究后发现,VLC播放器提供了libvlc,其LGPL-2.1授权允许在不修改源码的情况下以动态库形式免费商用,这成为集成libvlc作为后端的合适方案。
实现MediaEngine接口的核心功能包括播放、暂停等操作,unity摆放源码同时注册媒体事件和视频NV帧事件回调。关键代码片段涉及在libvlc的锁回调中锁定内存以用于写入视频数据。通过使用libvlc的回调模式格式设置,需特别注意为NV格式指定第二个平面的pitch和lines。
为了在Ubuntu .+系统上编译运行axmol引擎,建议下载引擎最新源码并根据指南进行编译。若遇到视频解码问题,茅台源码GitHub可安装ubuntu扩展组件以解决,使用命令:sudo apt install ubuntu-restricted-extras。
至此,axmol引擎的ui::MediaPlayer功能实现了全部平台上的视频纹理渲染播放,这得益于MediaEngine框架的重新设计。该框架不仅在axmol引擎内运行良好,还能独立编译,相册案例源码例如作者编写的bgfx视频播放示例:bgfx-axplay。
值得注意的是,libvlc是跨平台的,因此VlcMediaEngine实现仅需简单配置即可在其他平台如Windows上运行。若在Windows上使用,还需设置vlc插件加载地址。
unimrcpclient源码分析mrcp components
配置样例包含六个部分。论坛布局源码
函数unimrcp_client_components_load主要负责这六个组件的加载,下面详细解析各个组件的加载过程。
加载resource组件时,其结构体mrcp_resource_t定义在mrcp_resource.h,字符串使用apt_str_table_item_t(定义在mrcp_resource_loader.c),mrcp_resource_loader_t和mrcp_resource_factory_t分别位于mrcp_resource_loader.c和mrcp_resource_factory.c。构造mrcp_resource_loader内部是mrcp_resource_factory_t *factory,factory通过mrcp_resource_factory_create构建,参数为MRCP_RESOURCE_TYPE_COUNT的第5个值,整型值为4。
加载sip-uac组件时,mrcp_sofia_client_config_t结构体(mrcp_sofiasip_client_agent.c)应用于sofia sip协议栈。默认端口和名称设定如下:config->local_port = DEFAULT_SIP_PORT; 默认端口为,config->user_agent_name = DEFAULT_SOFIASIP_UA_NAME; 默认agent name为UniMRCP SofiaSIP,config->origin = DEFAULT_SDP_ORIGIN; 默认sdp origin为UniMRCPClient。IP地址配置通过unimrcp_client_ip_address_get(unimrcp_client.c)实现,可配置为“auto”或“iface”。然后使用mrcp_sofiasip_client_agent_create(mrcp_sofiasip_client_agent.c)创建sofiasip_client。
加载rtsp-uac组件时,指代MRCPv1版本的uac组件。rtsp_client_config_t结构体(mrcp_unirtsp_client_agent.h)用于配置。组件加载通过unimrcp_client_rtsp_uac_load函数完成。
加载media-engine组件时,配置项仅包含realtime_rate。unimrcp_client_media_engine_load函数负责加载此组件。mpf_engine_t结构体(mpf_engine.c)用于创建mpf_engine,使用mpf_engine_create函数。
加载rtp-factory组件时,mpf_rtp_config_t结构体(mpf_rtp_descriptor.h)包含可配置项。unimrcp_client_rtp_factory_load函数用于加载此组件,并通过mpf_rtp_termination_factory_create(mpf_rtp_termination_factory.c)创建相应的工厂。
è°è°MediaStream
MediaStream æ¯è¿æ¥ WebRTC API ååºå±ç©çæµçä¸é´å±ï¼webRTCå°é³è§é¢ç»è¿Vocie / Video engineè¿è¡å¤çåï¼åéè¿MediaStream APIç»æ´é²ç»ä¸å±ä½¿ç¨ã
MediaStreamTrackæ¯WebRTCä¸çåºæ¬åªä½åä½ï¼ä¸ä¸ªMediaStreamTrackå å«ä¸ç§åªä½æºï¼åªä½è®¾å¤æå½å¶å 容ï¼è¿åçåä¸ç±»åçåªä½ï¼å¦é³é¢ï¼è§é¢ï¼ãå个轨éå¯å å«å¤ä¸ªé¢éï¼å¦ç«ä½å£°æºå°½ç®¡ç±å¤ä¸ªé³é¢è½¨éææï¼ä½ä¹å¯ä»¥çä½æ¯ä¸ä¸ªè½¨éã
WebRTC并ä¸è½ç´æ¥è®¿é®æè æ§å¶æºï¼å¯¹æºçä¸åæ§å¶é½å¯ä»¥éè¿è½¨éæ§å¶ MediaTrackConstraints è¿è¡å®æ½ã
MediaStreamTrack MDNææ¡£
MediaTrackConstraints MDNææ¡£
MediaStreamæ¯MediaStreamTrackçåéï¼å¯ä»¥å å« >=0 个 MediaStreamTrackãMediaStreamè½å¤ç¡®ä¿å®æå å«çææ轨éé½æ¯æ¯åæ¶ææ¾çï¼ä»¥å轨éçåä¸æ§ã
MediaStream MDNææ¡£
åMediaTrackçæºç ä¸ï¼MediaTracké½æ¯ç±å¯¹åºçsourceåsinkç»æçã
æµè§å¨ä¸åå¨ä»sourceå°sinkçåªä½ç®¡éï¼å ¶ä¸sourceè´è´£ç产åªä½èµæºï¼å æ¬å¤åªä½æ件ï¼webèµæºçéæèµæºä»¥å麦å é£ééçé³é¢ï¼æå头ééçè§é¢çå¨æèµæºãèsinkåè´è´£æ¶è´¹sourceç产åªä½èµæºï¼ä¹å°±æ¯éè¿<img>ï¼<video>ï¼<audio>çåªä½æ ç¾è¿è¡å±ç¤ºï¼æè æ¯éè¿RTCPeerConnectionå°sourceéè¿ç½ç»ä¼ éå°è¿ç«¯ãRTCPeerConnectionå¯åæ¶æ®æ¼sourceä¸sinkçè§è²ï¼ä½ä¸ºsinkï¼å¯ä»¥å°è·åçsourceéä½ç çï¼ç¼©æ¾ï¼è°æ´å¸§ççï¼ç¶åä¼ éå°è¿ç«¯ï¼ä½ä¸ºsourceï¼å°è·åçè¿ç«¯ç æµä¼ éå°æ¬å°æ¸²æã
source ä¸sinkææä¸ä¸ªMediaTrackï¼å¤ä¸ªMeidaTrackææMediaStramã
MediaTrackConstraints æè¿°MediaTrackçåè½ä»¥åæ¯ä¸ªåè½å¯ä»¥éç¨çä¸ä¸ªæå¤ä¸ªå¼ï¼ä»èè¾¾å°éæ©åæ§å¶æºçç®çã MediaTrackConstraints å¯ä½ä¸ºåæ°ä¼ éç» applyConstraints() 以达å°æ§å¶è½¨éå±æ§çç®çï¼åæ¶å¯ä»¥éè¿è° getConstraints() ç¨æ¥æ¥çæè¿åºç¨èªå®ä¹çº¦æã
å¯å°MediaStream对象ç´æ¥èµå¼ç» HTMLMediaElement æ¥å£ç srcObject å±æ§ã
srcObject MDNææ¡£
å¯éè¿è°ç¨ MediaDevices.getUserMedia() æ¥è®¿é®æ¬å°åªä½ï¼è°ç¨è¯¥æ¹æ³åæµè§å¨ä¼æ示ç¨æ·ç»äºä½¿ç¨åªä½è¾å ¥ç许å¯ï¼åªä½è¾å ¥ä¼äº§çä¸ä¸ª MediaStream ï¼éé¢å å«äºè¯·æ±çåªä½ç±»åç轨éãæ¤æµå¯ä»¥å å«ä¸ä¸ªè§é¢è½¨éï¼æ¥èªç¡¬ä»¶æè èæè§é¢æºï¼æ¯å¦ç¸æºãè§é¢éé设å¤åå±å¹å ±äº«æå¡ççï¼ãä¸ä¸ªé³é¢è½¨éï¼åæ ·æ¥èªç¡¬ä»¶æèæé³é¢æºï¼æ¯å¦éº¦å é£ãA/D转æ¢å¨ççï¼ï¼ä¹å¯è½æ¯å ¶å®è½¨éç±»åã
éè¿ MediaDevices.enumerateDevices() æ们å¯ä»¥å¾å°ä¸ä¸ªæ¬æºå¯ç¨çåªä½è¾å ¥åè¾åºè®¾å¤çå表ï¼ä¾å¦éº¦å é£ï¼æåæºï¼è³æºè®¾å¤çã
å表ä¸çæ¯ä¸ªåªä½è¾å ¥é½å¯ä½ä¸ºMediaTrackConstraintsä¸å¯¹åºç±»åçå¼ï¼å¦ä¸ä¸ªé³é¢è®¾å¤è¾å ¥audioDeviceInputå¯è®¾ç½®ä¸ºMediaTrackConstraintsä¸audioå±æ§çå¼
å°è¯¥constraintå¼ä½ä¸ºåæ°ä¼ å ¥å° MediaDevices.getUserMedia(constraints) ä¸ï¼ä¾¿å¯è·å¾è¯¥è®¾å¤çMediaStreamã
MediaDevices.enumerateDevices() MDNææ¡£
MediaDevices.getUserMedia() MDNææ¡£
ä½¿ç¨ MediaDevices.getDisplayMedia() æ¹æ³ï¼å¯ä»¥æ示ç¨æ·å»éæ©åæææè·å±ç¤ºçå 容æé¨åå 容ï¼å¦ä¸ä¸ªçªå£ï¼ï¼å¹¶å°å½å¶å 容å¨ä¸ä¸ª MediaStream éã
MediaDevices.getDisplayMedia() MDNææ¡£
ä½¿ç¨ HTMLCanvasElement.captureStream() æ¹æ³è¿åç CanvasCaptureMediaStream æ¯ä¸ä¸ªå®æ¶æè·çcanvaså¨ç»æµã
HTMLCanvasElement.captureStream() MDNææ¡£
CanvasCaptureMediaStream MDNææ¡£
å¯éè¿æé å½æ° MediaStream() è¿åæ°å»ºç空ç½ç MediaStream å®ä¾
MediaRecorder MDNææ¡£