之前文章中介绍过通过youtube官方提供的android sdk 来集成youtube视频播放
但从2023 年 5 月 9 日开始,官方已经彻底废弃了此中sdk集成方式
修订历史记录 | YouTube Android Player API | Google for Developers
官方现在推荐所有平台都统一使用YouTube iframe Player API方式集成,不再需要依赖谷歌服务GoogleService和Youtube.apk,也就是通过webview形式
加载一个本地HTML,然后通过与JS通讯进行播控,官方提供的HTML如下:
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '360',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
将HTML文件放置到assets文件夹中,然后通过webview进行加载即可。
WebView mWebView = (WebView) findViewById(R.id.webview);
WebSettings mWebSettings = mWebView.getSettings();
mWebSettings.setJavaScriptEnabled(true);
mWebView.setWebViewClient(new MyWebViewClient());
mWebView.loadUrl("file:///android_asset/index.html");//工程目录assets index.html文件
具体播放控制参考官方API接口文档即可。
GitHub上有开源项目把这种形式也进行了封装,基本达到了和sdk集成方式一样的简易快捷集成方式。地址如下:
使用很简单:
dependencies {
implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:12.1.0'
}
YouTubePlayerView youTubePlayerView = findViewById(R.id.youtube_player_view);
getLifecycle().addObserver(youTubePlayerView);
youTubePlayerView.addYouTubePlayerListener(new AbstractYouTubePlayerListener() {
@Override
public void onReady(@NonNull YouTubePlayer youTubePlayer) {
String videoId = "5DZhwuUxbEw";
youTubePlayer.loadVideo(videoId, 0);
}
});
关于youtube 播放列表数据相关可查询官方数据获取API:
YouTube Data API 概览 | Google for Developers
市面上也有一些很优秀的youtube开源应用,如 NewPipe、smarttube_stable都不需要依赖GoogleService
NewPipe 项目地址:GitHub - TeamNewPipe/NewPipe: A libre lightweight streaming front-end for Android.
做手机应用到这里基本就能顺利集成最新API了,但如果是做ROM开发,基于不同平台方案定制化开发,就还需要注意一些坑。比如我工作中需要同时在RK、全志、海思平台上进行适配,过程中出现在全志平台无法播放,其他平台可以正常播放。
后面发现是因为Youtube视频是VP9格式的,我手上的全志SDK版本比较老,还没有支持VP9解码器,然后跟厂商沟通,拿到了解码器补丁。
解码器代码相关目录:
android\frameworks\av\media\libcedarc
主要是更新vp9解码器相关的so库
解码器配置表目录:
android/device/softwinner/petrel-common/media_codecs.xml
<MediaCodec name="OMX.allwinner.video.decoder.vp9" type="video/x-vnd.on2.vp9" >
<Quirk name="requires-allocate-on-input-ports" />
<Quirk name="requires-allocate-on-output-ports" />
<Limit name="size" min="32x32" max="4096x2160" />
<Limit name="alignment" value="2x2" />
<Limit name="block-size" value="16x16" />
<Limit name="blocks-per-second" min="1" max="489600" />
<Limit name="bitrate" range="1-30000000" />
<Limit name="concurrent-instances" max="8" />
<Feature name="adaptive-playback" />
</MediaCodec>
到这一步,想着总该可以了吧,开开心心跑起来,emo...还是太年轻了
的确能播,但每次初始化会失败,要手动重播一下才行,但平台厂商那边测试是正常的,一番折腾后,看日志中总是报错如下:
原来是VP9解码器会在生成一个/dev/googlevp9_dev 设备节点,这个设备一直打开失败,猜想应该是权限问题,查看权限 为600,的确无法执行。于是执行chmod 777 /dev/googlevp9_dev 修改为完全可读写权限,到此终于能正常在全志平台上播放youtube视频了。
这次youtube更新API,前后折腾了好几天,记录一下。