Picture-in-Picture API是一个新的h5小游戏程序源码API,它允许网站在一个小的浮动窗口中播放视频,即使浏览器不可见,该窗口仍位于其他窗口的顶部,允许我们在与交互的同时继续观看这些视频其他网站或应用程序。
该API目前于视频元素。幸运的是,我们还可以从画布元素创建视频流。这意味着我们可以在画布上绘制任何东西并将其显示在画中画窗口中。
仓库源码:y.wxlbyx.icu
我们可以从Chromium存储库中获取游戏的源代码。我们复制该位置的内容,重命名一些文件,并清理HTML以仅包含以下必要的标记:

<!–This will contain the canvas element–>
<div class=”interstitial-wrapper”></div>
<!–Game assets:sprits+audio–>
<div id=”offline-resources”>
<img id=”offline-resources-1x”src=”images/100-percent/100-offline-sprite.png”>
<img id=”offline-resources-2x”src=”images/200-percent/200-offline-sprite.png”>
<div id=”audio-resources”>
<audio id=”offline-sound-press”src=”sounds/button-press.mp3″></audio>
<audio id=”offline-sound-hit”src=”sounds/hit.mp3″></audio>
<audio id=”offline-sound-reached”src=”sounds/score-reached.mp3″></audio>
</div>
</div>
<!–The main game script–>
<script src=”offline.js”></script>
<!–Initialize the canvas and the game.–>
<!–Originally performed inside neterror.js–>
<script>
const runner=new Runner(.interstitial-wrapper);
</script>
这为我们提供了我们已经可以玩的离线T-Rex跑步游戏的精确复制品:
离线T-Rex Runner副本
实现程序化的霸王龙跳跃
每次我们按下空格键时,T-Rex都会跳跃。让我们添加一种以编程方式使我们的T-Rex跳跃的方法,而无需实际按下空格键。
挖掘游戏代码,我们会发现runner处理空格键的对象有两个方法:
onKeyDown,使T-Rex在游戏运行时跳跃。
onKeyUp,当T-Rex撞到障碍物时重新开始游戏。
让我们编写一个基于游戏状态调用其中任何一个的方法,传入一个虚拟键盘事件。
function simulateSpacebar(){
const keyboardEventOptions={
code:Space,
keyCode:32,
};
if(runner.crashed){
const event=new KeyboardEvent(keyup,keyboardEventOptions);
runner.onKeyUp(event);
}else{
const event=new KeyboardEvent(keydown,keyboardEventOptions);
runner.onKeyDown(event);
}
}
捕获画布内容的视频流
调用new Runner(…)创建一个画布元素并将其插入到页面中。我们需要获取对该画布元素的引用,然后将其内容捕获为视频流:
const canvas=document.querySelector(canvas);
const videoStream=canvas.captureStream();
然后我们创建一个video以视频流为源的元素:
const video=new Video();
video.srcObject=videoStream;
video.muted=true;
video.play();
在这里,我们还将视频静音,以便我们可以自动播放它(请参阅Chrome的自动播放政策)。
显示画中画窗口
在使用新的Web API(如画中画)时,请始终在尝试使用它们之前检测它们是否可用。这可以确保我们的应用在API不可用时不会中断,并且只会在API可用时逐步增强体验。对于画中画,可以通过检查document.pictureInPictureEnabled属性来完成:
const button=document.querySelector(button);
if(document.pictureInPictureEnabled){
//Picture-in-Picture is available!
//Subsequent code snippets will be place inside this block.
}else{
//Picture-in-Picture is not available.User can still play the game normally in the page.
button.textContent=Picture-in-Picture is not available;
button.disabled=true;
}
我们还在<button>页面中添加了一个元素,用户可以点击
进入画中画。我们希望将这种控制权交给我们的用户,通常是通过UI中的画中画图标,以便他们可以决定何时要在画中画窗口中查看我们的内容。
现在到了有趣的部分,让我们在单击按钮时在画中画窗口中显示我们的视频流!
button.addEventListener(click,async()=>{
simulateSpacebar();
await video.requestPictureInPicture();
});
结果如下所示:
实现游戏控制
画中画窗口可以停留在其他应用程序窗口的顶部,在这种情况下,我们将无法在页面上按空格键进行T-Rex跳跃,因此我们需要另一种方法来实现它去做。
媒体会话API来救援!
媒体会话API允许网站自定义媒体通知,以及为播放控制定义事件处理程序(例如播放、暂停等)。每当我们按下键盘(或其他可以控制媒体播放的设备)上的播放/暂停按钮时,我们可以通过定义play和pause事件处理程序使我们的T-Rex跳跃。
navigator.mediaSession.setActionHandler(play,simulateSpacebar);
navigator.mediaSession.setActionHandler(pause,simulateSpacebar);
画中画API与媒体会话API很好地集成在一起。当我们定义播放事件处理程序时,画中画窗口也会显示它们对应的操作按钮。
让我们玩!
完成所有这些更改后,我们现在使T-Rex Runner游戏
可在画中画窗口中玩,使用我们的播放/暂停媒体按钮让T-Rex跳跃!
结论
在本文中,我们能够使用画中画API和媒体
会话API来构建一些愚蠢的东西。这些API有更严肃和有用的用途——Youtube在他们的播放器控件中有一个隐藏的画中画按钮,在我进行这个实验之前,我还构建了一个在画中画中显示音频可视化的演示窗口使用本文中的相同技术。