深入理解Google Cast(三)探寻原理

2023-11-13

如何开发一个receiver application

先来简单说一下这个话题。

Receiver本质就是一个网页,由html+CSS和jacascript开发,如果要自定义receiver application,需要在 Google Cast SDK Developer Console注册appID,这个appID将会包含在sender的SDK方法中,标识receiver app,注册收费5$.For more details, see below:
https://developers.google.com/cast/docs/receiver_apps

去哪里找源码

1、
https://support.google.com/googlecast/answer/6121012?hl=zh-Hans
在上面这个页面我们能找到链接,只能用google drive全部下载下来才能看。
下载得到的是chromecast_media_shell_arm.tar.gz
解压源码,在readme中看到

To rebuild libcast_shell_android.so:

1) Extract this archive.

2) From the out_arm_android/Release directory of the archive, execute:

../../third_party/android_tools/ndk//toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++ -shared -Wl,-z,now -Wl,-z,relro -Wl,--fatal-warnings -Wl,-z,defs -Wl,-z,noexecstack -fPIC -B../../third_party/binutils/Linux_x64/Release/bin -Wl,-z,relro -Wl,-z,now -fuse-ld=gold -static-libstdc++ -static-libgcc -Wl,--build-id=sha1 -Wl,--no-undefined --sysroot=../../third_party/android_tools/ndk//platforms/android-16/arch-arm -nostdlib -L../../third_party/android_tools/ndk//sources/cxx-stl/llvm-libc++/libs/armeabi-v7a -Wl,--exclude-libs=libgcc.a -Wl,--exclude-libs=libc++_static.a -Wl,--exclude-libs=libcommon_audio.a -Wl,--exclude-libs=libcommon_audio_neon.a -Wl,--exclude-libs=libcommon_audio_sse2.a -Wl,--exclude-libs=libiSACFix.a -Wl,--exclude-libs=libisac_neon.a -Wl,--exclude-libs=libopus.a -Wl,--exclude-libs=libvpx.a -Wl,--icf=all -Wl,-shared,-Bsymbolic -Wl,--version-script=../../build/android/android_no_jni_exports.lst -Wl,-O1 -Wl,--as-needed -Wl,--gc-sections -Wl,--warn-shared-textrel -o libcast_shell_android.so -Wl,-soname=libcast_shell_android.so @libcast_shell_android.so.rsp

所以这一套源码最终用于生成一个so库,那么这个库给谁用?
往下看

2、
https://chromium.googlesource.com/chromium/src/+/master/chromecast/
这里是chromium项目中的chromecast部分源码
在他的chromecast.gyp文件中,看到下面的内容


{
	          'target_name': 'cast_shell_apk',
	          'type': 'none',
	          'dependencies': [
	            'cast_shell_java',
	            'libcast_shell_android',
	          ],
	          'variables': {
	            'apk_name': 'CastShell',
	            'manifest_package_name': 'org.chromium.chromecast.shell',
	            # Note(gunsch): there are no Java files in the android/ directory.
	            # Unfortunately, the java_apk.gypi target rigidly insists on having
	            # a java_in_dir directory, but complains about duplicate classes
	            # from the common cast_shell_java target (shared with internal APK)
	            # if the actual Java path is used.
	            # This will hopefully be removable after the great GN migration.
	            'java_in_dir': 'android',
	            'android_manifest_path': 'shell/android/apk/AndroidManifest.xml',
	            'package_name': 'org.chromium.chromecast.shell',
	            'native_lib_target': 'libcast_shell_android',
	            'asset_location': '<(PRODUCT_DIR)/assets',
	            'additional_input_paths': ['<(PRODUCT_DIR)/assets/cast_shell.pak'],
	          },
	          'includes': [ '../build/java_apk.gypi' ],
	        }

可以看到在build – cast_shell.apk的时候需要前面的libcast_shell_android.so
那么是否编出来的这个cast_shell.apk就是实际的AndroidTV中的那个Google Cast呢?

直接find查找一下,真的找到了
./data/data/com.google.android.apps.mediashell/app_cast_shell/cast_shell
但是我们自己build出来的,还跟实际电视中的不一样,详见
https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/android_cast_build_instructions.md
此外,在https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/Me78B_4Q4jU 这里也看到

Build/install as described here: https://www.chromium.org/developers/how-tos/build-instructions-cast

As stated there, that apk is not functionally equivalent to Google's Cast apk (which is built with additional non-public code).

综上,关于源码的问题,总结如下:

  • Google Cast SDK完全闭源
  • Android TV的Google Cast Receiver部分开源,开源的部分在chromium项目源码的chromecast部分,既包含了libcast_shell_android.so依赖的c源文件,又包含了build apk的java文件,但是build这部分源码不能得到和实际TV中的Google Cast Receiver完全一样的东西,还是有一部分代码闭源。实际经验来说,build能成功,但是build出来的chromecast Android Shell apk会crash,不能用,找不到解决方案。

集合log和抓包文件做一些分析

如何找到局域网内的设备的

mDNS协议
Multicast DNS is a way of using familiar DNS programming interfaces, packet formats and operating semantics, in a small network where no conventional DNS server has been installed.
mDNS 协议规定了一个端口,5353。mDNS 基于 UDP 协议。每个进入局域网的主机,如果开启了mDNS服务的话,都会向局域网内的所有主机组播一个消息,我是谁,和我的IP地址是多少。然后其他也有该服务的主机就会响应,也会告诉你,它是谁,它的IP地址是多少。

如何传递控制信息

TLS – 传输层安全协议,encrypted and Json encoded
Detail:https://github.com/thibauts/node-castv2#protocol-description
Example:{ “type”: “STOP”, sessionId: } stops a running instance of an application

Mediaplayback Message
For more details, see below
https://developers.google.com/cast/docs/reference/messages

随log结合java部分源码做流程简述

Line6603
08-30 19:18:32.102  3901  3901 D cr.CastShellActivity: Using scale factor 1.5 to set height 720
08-30 19:18:32.103  3901  3901 D cr.CastShellActivity: onCreate startupUrl: https://storage.googleapis.com/cast-reference-receiver/player.html

CastShellActivity:Activity for managing the Cast shell.
mNativeCastWindow = mCastWindowManager.launchCastWindow(url);

Line6645
08-30 19:18:32.881  3901  3901 I chromium: [3901:3901:INFO:CONSOLE(64)] " [  0.152s] [cast.receiver.CastReceiverManager] Version: 2.0.0.0044", source: https://www.gstatic.com/cast/sdk/libs/receiver/2.0.0/cast_receiver.js (64)
加载js,receiver SDK
Line6646
08-30 19:18:32.893  3901  3901 I chromium: [3901:3901:INFO:v2_ipc_message_sender.cc(49)] Cast V2 IPC connected: app_id=4F8B3483
Appid:注册在google服务器的id,标识自制的receiver app
Line6650
08-30 19:18:33.182  3901  3901 V CastWindowAndroid: Broadcast ACTION_PAGE_LOADED: scheme=https, host=storage.googleapis.com

CastWindowAndroid:Container for the various UI components that make up a shell window.
called in:CastWindowAndroid.initFromNativeWebContents
initFromNativeWebContents:Initializes the ContentView based on the native tab contents pointer passed in nativeWebContents The pointer to the native tab contents object.

<org.chromium.chromecast.shell.CastWindowAndroid
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <FrameLayout android:id="@+id/contentview_holder"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</org.chromium.chromecast.shell.CastWindowAndroid>

Line6651
08-30 19:18:33.182  3901  3901 D MediaShellActivity: Received intent: action=castPageLoaded
Line6653
08-30 19:18:33.183  3901  3901 I chromium: [3901:3901:INFO:application_manager_impl.cc(770)] App started: 4F8B3483, instance=mediashell-8
08-30 19:18:33.185  3901  4049 I chromium: [3901:4049:INFO:v2_transport.cc(611)] Heartbeat for V2Transport started: max_inactivity=10000000, heartbeat_interval_=5000000
08-30 19:18:33.186  3901  3901 I chromium: [3901:3901:INFO:application_manager_impl.cc(775)] App running: 4F8B3483, instance=mediashell-8

Receiver application启动了

Line6705
08-30 19:18:36.971   611   633 W WebKit  : HTMLMediaElement::loadResource(0x20c5c000, https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/mp4/DesigningForGoogleCast.mp4, , )
08-30 19:18:36.971   611   633 W WebKit  : HTMLMediaElement::loadResource(0x20c5c000) - m_currentSrc -> https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/mp4/DesigningForGoogleCast.mp4
Line6715
08-30 19:18:37.524  1688  2743 V MstMetadataRetriever: [MstMeta] setDataSource(https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/mp4/DesigningForGoogleCast.mp4)
08-30 19:18:37.529  1688   658 D Downloader: [StartTask] [0xab9b0080]url :https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/mp4/DesigningForGoogleCast.mp4
download to parse metadata
Line7210
08-3008-30 19:18:40.889   611   633 W WebKit  : HTMLMediaElement::play(0x20c5c000)
Line7237
08-30 19:18:40.906  1688 31668 D mstplayer: [31668] (0x0xab95a5d8)MstPlayer::setDataSource: https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/mp4/DesigningForGoogleCast.mp4

简单的通过http下载流,系统播放器播放流,显示在刚才的framelayout上,也即是CastWindowAndroid

Line7271
08-30 19:18:40.908  3901  3901 V MediaPlayer: start, Application: org.chromium.chromecast.shell.CastApplication@bfcbad8

CastApplication:Entry point for the Android cast shell application
CastApplication is called by CastBrowserHelper in initializeBrowser function
CastBrowserHelper:Static, one-time initialization for the browser process.
initializeBrowser:Starts the browser process synchronously, returning success or failure. If the browser has already started, immediately returns true without performing any more initialization. This may only be called on the UI thread.
CastBrowserHelper is called by CastShellActivity in onCreate function

Line7321
08-30 19:18:40.913  1688   676 D Downloader: [StartTask] [0xab7b94b8]url :https://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/mp4/DesigningForGoogleCast.mp4
download for real play
Line 7771
08-30 19:18:42.666  1679  1896 D vsyncbridge: Init Overlay 0
render start

综上,Android TV上的这个Google Cast Receiver(cast_shell apk)有以下几个点值得注意

  • receiver application是个网页,Google Cast SDK提供了js语言的API用于做一些控制操作,都对应到cast_shell apk的CastWindowAndroid,本质是一个framelayout,但是利用chromium / content_public / browser / WebContents.java方法将网页的css等元素以及javascript内容都包含了进去,用的是initFromNativeWebContents方法。这部分的原理是chromium的内容,不用管他。
  • cast_shell apk中CastShellActivity, CastWindowAndroid, and native CastWindowAndroid have a one-to-one relationship,很好理解。
  • 视频的解码播放还是用的系统原生播放器、解码器,显示在framelayout上。

关键log流程详述-包含sender端和receiver端

请添加图片描述

欢迎关注我的公众号灰度五十,分享各类音视频、移动开发知识~
在这里插入图片描述

文章帮到你了?可以扫描如下二维码进行打赏,打赏多少您随意~
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解Google Cast(三)探寻原理 的相关文章

随机推荐

  • NFT颓势已现:肝不起了,卷不动了

    白名单制度是时候变革了 作者 星球小花 出品 Odaily星球日报 ID o daily 前几天 一位朋友问我 几个月没关注 NFT 了 你们怎么还在抢 PFP 我也反驳了一番 现在有很多圈外流量涌入 巨头纷纷进场 应用遍地开花 不过仔细想
  • C++中typeid的使用

    RTTI Run TimeType Information 运行时类型信息 它提供了运行时确定对象类型的方法 在C 中 为了支持RTTI提供了两个操作符 dynamic cast和typeid The typeid operator pro
  • 基于机器学习的文本分类!

    关注后 星标 Datawhale 每日干货 每月组队学习 不错过 Datawhale干货 作者 李露 西北工业大学 Datawhale优秀学习者 据不完全统计 网民们平均每人每周收到的垃圾邮件高达10封左右 垃圾邮件浪费网络资源的同时 还消
  • 基于Open CV的植物图像分类识别项目

    一 项目简介 1 主要内容 本项目主要是基于Open CV进行植物图像进行分类识别 展示部分采用了网页的形式 Vue Element net Core 由用户上传图片 服务器返回该图片的分类结果 Web服务 net Core 和c 图像处理
  • 《利用Python 进行数据分析》第四章:Numpy基础

    对 利用Python 进行数据分析 Wes Mckinney著 一书中的第四章中Numpy基础进行代码实验 原书中采用的是Python2 7 而我采用的Python3 7在Pycharm调试的 因此对书中源代码进行了一定的修改 每步打印结果
  • iOS开发常见错误代码对照表整理

    登录 注册 一样的世界 不一样的时间 随手记点东西 目录视图 摘要视图 订阅 2016软考项目经理实战班
  • 软件测试的缺陷管理与分析,粉丝福利拿走不谢

    软件测试过程中提交缺陷是测试工程师最常做的一件事 也是开发工程师解决问题的依据 所以需要对缺陷进行管理和分析 缺陷管理主要是管理从提交缺陷到解决缺陷这一系列的过程 包括流程中角色的变换 缺陷分析主要对测试过程中所发现的缺陷进行分类分析 分析
  • Java学习笔记(十四)

    Java 中的异常处理 在 Java 中 所有的异常都有一个共同的祖先 java lang 包中的 Throwable 类 Throwable 有两个重要的子类 Exception 异常 和 Error 错 误 二者都是 Java 异常处理
  • OSM数据下载及两种格式转换方法(shp等格式)

    OSM数据下载及两种常用的格式转换方法 1 首先打开OSM官网 https www openstreetmap org 2 先注册账号 再选择左上角的 导出 3 点击 手动选择不同的区域 4 导出即可 5 格式准换可以考虑以下两种方法 一是
  • mysql官网安装步骤_MySQL的安装与配置——详细教程

    免安装版的Mysql MySQL关是一种关系数据库管理系统 所使用的 SQL 语言是用于访问数据库的最常用的 标准化语言 其特点为体积小 速度快 总体拥有成本低 尤其是开放源码这一特点 在 Web 应用方面 MySQL 是最好的 RDBMS
  • 2022年度总结 EXI-小洲

    文章目录 一 第一次自我介绍 二 2022我都干了些什么 我的收获 1 大专顺利毕业 2 后端开发辞职 3 第二次代表学校参加江西省职业院校大数据技能大赛 4 专升本考试 5 参加泰迪杯第五届 数据分析技能赛 6 在csdn开始写博文 7
  • 常见渗透测试靶场系统

    常见靶场 DVWA Dam Vulnerable Web Application DVWA是用PHP Mysql编写的一套用于常规WEB漏洞教学和检测的WEB脆弱性测试程序 包含了SQL注入 XSS 盲注等常见的一些安全漏洞 链接地址 ht
  • Java中JSON字符串和Java对象的互转

    1 JSON数据和Java对象的相互转换 JSON数据和Java对象的相互转换 JSON解析器 常见的解析器 Jsonlib Gson fastjson jackson 1 Java对象转换JSON 1 使用步骤 1 导入jackson的相
  • python中的库和模块有什么区别_Python中的模块和库之间有什么区别?

    从 The Python Tutorial Modules gt 模块 A module is a file containing Python definitions and statements The file name is the
  • 美团面试官问:写一个你认为最好的单例模式?于是我写了7个

    各位CSDN的朋友 如果喜欢我的文章 记得点个关注 方便以后找到我 由于是刚开始创作 推荐量较低 如果不关注 以后就可能找不到我了 面试题 写一个你认为最好的单例模式 面试考察点 考察目的 单例模式可以考察非常多的基础知识 因此对于这种问题
  • 软考-中级-网络工程师-知识点个人总结(九)

    1 CPU部件 运算器 控制器 寄存器 运算器 算术逻辑运算器 累加器 数据缓冲寄存器 状态条件寄存器 控制器 程序计数器 指令寄存器 指令译码器 时序部件 2 测试依据 测试类型 测试内容 测试依据 黑盒测试 功能测试 对软件的每个功能进
  • 小程序里的alert,Toast

    前言 在小程序中的弹框写法和我们在外面直接用是不一样的 他不支持alert 但是有替代的弹框组件 目录 一 原生小程序 原生小程序api 二 vant中的提示框 官网入口 vant api 一 原生小程序 wx showToast titl
  • C# MSChart 中柱状图和X轴自定义标签

    C 中MSChart 里面曲线 柱状图的样式选择是由 chart Series ChartType SeriesChartType Column 来控制的 SeriesChartType列举出了所有的样式 如果要在X轴上显示自己的文本标签
  • ChatGPT和代码智能

    一 ChatGPT 1 ChatGPT的自我介绍 2 ChatGPT的前世 2 1GPT 3是啥 General Pre Training GPT 即通用预训练语言模型 是一种利用Transformer作为特征抽取器 基于语言模型进行训练的
  • 深入理解Google Cast(三)探寻原理

    如何开发一个receiver application 先来简单说一下这个话题 Receiver本质就是一个网页 由html CSS和jacascript开发 如果要自定义receiver application 需要在 Google Cas