浏览器环境:微信浏览器!!!只兼容了微信浏览器,safari等其他的浏览器不知道,没测试!!。
一、视频播放问题
需求:当用户进入页面时,视频当作背景,自动循环播放。
1. 视频全屏显示
<video
webkit-playsinline="true"
id="activeVideo"
playsinline="true"
x5-video-player-type="h5-page"
class="video example_video"
:controls="false"
:muted="true"
:autoplay="true"
loop
x5-video-player-fullscreen="false"
src=""
/>
//视频资源通过接口动态获取
const res: any = await API.getVirtualAvatar(payload);
let restVideo = document.querySelector("#restVideo") as any;
let activeVideo = document.querySelector("#activeVideo") as any;
restVideo.src = res.data.data.rest_url;
activeVideo.src = res.data.data.interactive_url;
//隐藏视频控件按钮
//全屏按钮
video.example_video::-webkit-media-controls-fullscreen-button {
display: none;
}
//播放按钮
video.example_video::-webkit-media-controls-play-button {
display: none;
}
//进度条
video.example_video::-webkit-media-controls-timeline {
display: none;
}
//观看的当前时间
video.example_video::-webkit-media-controls-current-time-display {
display: none;
}
//剩余时间
video.example_video::-webkit-media-controls-time-remaining-display {
display: none;
}
//音量按钮
video.example_video::-webkit-media-controls-mute-button {
display: none;
}
video.example_video::-webkit-media-controls-toggle-closed-captions-button {
display: none;
}
//音量的控制条
video.example_video::-webkit-media-controls-volume-slider {
display: none;
}
//所有控件
video.example_video::-webkit-media-controls-enclosure {
display: none;
}
PS:在电脑端上的谷歌浏览器上看,已经完美的满足了需求,但是从移动端打开发现,视频压根不会自动播放。
原因:为节约用户流量,移动端不允许视频自动播放,一定需要和用户交互后才能调用视频播放api。 解决办法:既然如此,那我只能加一个弹窗引导用户点击,然后播放视频了。。。
2. 解决移动端视频不能自动播放的问题
- IOS端可以通过 微信内置浏览器私有接口WeixinJSBridge 去实现 已进入页面视频自动播放的操作。
if ((window as any).WeixinJSBridge) {
WeixinJSBridge.invoke("getNetworkType", {}, function (e) {
document.querySelector(".video").play()
});
}
- 安卓端用WeixinJSBridge无效,一定要加一个弹窗和用户交互后才能播放视频。
当你满意的交付需求后,测试又提bug了。。。。。
二、IOS端:将页面切换到后台后再回来视频就不动了
ps:幸好安卓没有这个问题哈哈
//监听页面显示隐藏
window.addEventListener("visibilitychange", () => {
if(ios){
if ((window as any).WeixinJSBridge) {
WeixinJSBridge.invoke("getNetworkType", {}, function (e) {
document.querySelector(".video").play()
});
}
}
});
二、音频——当页面切换到后台再切回前台后,音频播放无效问题
上源代码
let audioContext=ref(null)
const play = () => {
// api: 获取音频流
const ttsResult = await API.textToVoice(params).data.data;
ttsBuffer.value += window.atob(ttsResult);
if (!audioContext.value) {
audioContext.value = new AudioContext({
sampleRate: 10000
});
}
let sourceCache = new Set();
let audioData = ttsBuffer.value.slice(ttsBufferOffset.value);
ttsBufferOffset.value += audioData.length;
if (audioData.length > 0) {
const outputS16 = base64ToS16(audioData);
const output = transS16ToF32(outputS16);
const audioBuffer = audioContext.value.createBuffer(
1,
output.length,
8000
);
audioBuffer.copyToChannel(new Float32Array(output), 0, 0);
bufferSource.value = audioContext.value.createBufferSource();
bufferSource.value.buffer = audioBuffer;
bufferSource.value.connect(audioContext.value.destination);
console.log("开始播放");
bufferSource.value.start();
sourceCache.add(bufferSource.value); // Tips:缓存住 source,防止被GC掉,GC掉的话音频会中断
$eventBus.emit("switchVideo", true);
bufferSource.value.onended = () => {
console.log("结束播放-onended");
isVoiceing.value = false;
$eventBus.emit("switchVideo", false);
sourceCache.delete(bufferSource.value); // Tips:播放完之后,再清掉source缓存
};
} else {
isVoiceing.value = true;
$eventBus.emit("switchVideo", true);
}
};
function base64ToS16(base64AudioData) {
const outputArray = new Uint8Array(base64AudioData.length);
for (let i = 0; i < base64AudioData.length; ++i) {
outputArray[i] = base64AudioData.charCodeAt(i);
}
return new Int16Array(new DataView(outputArray.buffer).buffer);
}
function transS16ToF32(input) {
let tmpData = [];
for (let i = 0; i < input.length; i++) {
let d = input[i] < 0 ? input[i] / 0x8000 : input[i] / 0x7fff;
tmpData.push(d);
}
return new Float32Array(tmpData);
}
问题描述:当页面切换到后台后,然后进入其他的app,再回来切回来后,点击音频播放按钮paly(); 音频不播放了。 解决方案:在页面隐藏后,将audioContext指向null
const initVisibilityEvent = () => {
window.addEventListener("visibilitychange", () => {
if (document.visibilityState !== "visible") {
console.log("页面隐藏");
audioContext.value = null;
}
});
};
onMounted(() => {
initVisibilityEvent();
});
- 移动设备的音频自动暂停:当页面切换到后台或用户切换到其他应用时,大多数移动浏览器会自动暂停所有音频播放以节省资源和电量。
- AudioContext 的状态:Web Audio API 的
AudioContext在被暂停后不会自动恢复。当页面重新变为可见时,AudioContext仍然处于suspended状态。 - 直接调用 play() 无效:在这种状态下直接调用
play()方法可能不会生效,因为音频上下文没有被正确恢复。
const initVisibilityEvent = () => {
window.addEventListener("visibilitychange", async () => {
if (document.visibilityState !== "visible") {
console.log("页面隐藏");
// 不需要设为null,只需暂停
if (audioContext.value) {
await audioContext.value.suspend();
}
} else {
console.log("页面可见");
// 页面重新可见时恢复AudioContext
if (audioContext.value) {
try {
await audioContext.value.resume();
} catch (e) {
console.error("恢复AudioContext失败:", e);
// 如果恢复失败,可以创建新的
audioContext.value = new (window.AudioContext || window.webkitAudioContext)();
}
}
}
});
};