微信小程序没有原生的视频字幕,由于需要,自己实现了字幕,字幕是由组件实现的,直接复制插件即可,index是引用Demo
我在这里用了两行字幕,可控制中文和英文,如有需要,可删掉一个
1. 项目结构
|–components (组件)
|
~~~~~~
|–track
|
~~~~~~
|
~~~~~~
|–track.js
|
~~~~~~
|
~~~~~~
|–track.json
|
~~~~~~
|
~~~~~~
|-track.wxml
|
~~~~~~
|
~~~~~~
L track.wxss
|–pages (示例页面)
|
~~~~~~
|–index
|
~~~~~~
|
~~~~~~
|–index.js
|
~~~~~~
|
~~~~~~
|–index.json
|
~~~~~~
|
~~~~~~
|-index.wxml
|
~~~~~~
|
~~~~~~
L index.wxss
|–app.js
|–app.json
|–app.wxss
2. 组件
track.wxml
<view class="zimu">
<view>{{enableEn ? en : ''}}</view>
<view>{{enableZh ? zh : ''}}</view>
</view>
track.js
// components/track/track.js
var zimuList = []; // 字幕集合
var currentZimuIndex = -1; // 当前字幕位置,-1表示还未开始
var fileSystemManager = wx.getFileSystemManager();
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
enableEn: true,
enableZh: true
},
/**
* 组件的方法列表
*/
methods: {
// 视频触发事件
videoChangeEvent: function (time) {
this.setZimu(time, currentZimuIndex)
},
// 设置字幕(展示字幕的重要环节)
setZimu: function(time, index) {
if (index >= zimuList.length) {
return;
}
// 如果需要移动字幕指针(即当前指向-1 或 当前视频进度大于当前字幕结尾的时间)
if (index == -1 || zimuList[index][2] < time) {
this.hideZimu();
this.setZimu(time, index + 1)
return;
}
else if (index != 0 && index != -1 && zimuList[index][1] > time && zimuList[index - 1][2] > time) {
this.hideZimu();
this.setZimu(time, (index - 1 < -1) ? -1 : (index - 1))
return;
}
// 如果未来指针大于当前指针并且当前视频进度 > 未来指针字幕的开始时间(-200ms)
if (index != currentZimuIndex && time > zimuList[index][1] - 250) {
currentZimuIndex = index;
this.showZimu(currentZimuIndex);
}
},
/**
* 字幕相关
*/
loadZimu: function (path, fileName) {
zimuList = [];
this.downloadZimu(path, fileName);
},
readZimu: function (fileName) {
console.info(wx.env.USER_DATA_PATH + '/' + fileName)
let fileStr = fileSystemManager.readFileSync(wx.env.USER_DATA_PATH + '/' + fileName, 'utf-8')
// 换行符转换
fileStr = fileStr.replace(new RegExp("\r\n", "gm"), '\n')
let list = fileStr.split('WEBVTT\n\n')[1].split('\n\n');
for (let i = 0; i < list.length; i++) {
if (list[i]) {
// 去除首位换行符
list[i] = list[i].replace(/^(\s|\n)+|(\s|\n)+$/g, '');
let a = list[i].split('\n');
let timeFrom = a[1].split(' --> ')[0];
let timeTo = a[1].split(' --> ')[1];
zimuList.push([a[0], this.getCurrentTime(timeFrom), this.getCurrentTime(timeTo), a[2], a[3]]);
}
}
},
downloadZimu: function (path, fileName) {
var that = this;
wx.downloadFile({
"url": path + fileName,
"filePath": wx.env.USER_DATA_PATH + '/' + fileName,
success: function (e) {
that.readZimu(fileName);
}
})
},
// 改变字幕
changeZimu: function (zh, en) {
this.setData({
zh,
en
})
},
// 隐藏字幕
hideZimu: function () {
this.changeZimu('', '');
},
// 展示字幕
showZimu: function (index) {
this.changeZimu(zimuList[index][4], zimuList[index][3]);
},
// 获取当前时间戳
getCurrentTime: function (time) {
let timeSplit = time.split(".");
let a = new Date('1970/01/01 ' + timeSplit[0]).getTime() + parseInt(timeSplit[1]) + 28800000; // 兼容iphone下的处理方法
return a;
},
}
})
track.json
{
"component": true,
"usingComponents": {}
}
track.wxss
/* components/track/track.wxss */
.zimu{
bottom:12px;
font-size: 22rpx;
position:absolute;
color:#fff;
width:80%;
padding:0 10%;
pointer-events:none;
text-align: center;
}
.zimu view{
pointer-events:none;
white-space: pre-wrap;
}
view {
display:block;
line-height:1.2;
overflow:hidden;
font-family:-apple-system;
}
示例页面 (部分)
index.html
<video src='https://www.lpsql.top/static/en/video/1.mp4' autoplay show-center-play-btn show-fullscreen-btn enable-progress-gesture bindtimeupdate="videoChange" >
<track id="track"/>
</video>
index.js
//index.js
Page({
data: {
},
onLoad: function () {
this.init();
},
// 初始化
init: function(){
// 加载字幕
this.selectComponent("#track").loadZimu('https://www.lpsql.top/static/en/s/', '1.vtt');
},
videoChange: function(e){
// 视频触发事件
this.selectComponent("#track").videoChangeEvent(e.detail.currentTime * 1000);
}
})
index.json
{
"usingComponents": {
"track":"/components/track/track"
}
}
index.wxss
/**index.wxss**/
video {
width: 100%;
}
效果
字幕格式
WEBVTT
1
00:00:01.600 --> 00:00:03.600
ACT 1
第一幕
2
00:00:06.900 --> 00:00:09.200
In New York Harbor
纽约港
3
00:00:11.900 --> 00:00:15.000
Excuse me. My name is Richard Stewart.
打扰一下 我叫理查德·斯图尔特
4
00:00:15.000 --> 00:00:16.000
I'm a photographer.
我是一名摄影师
5
00:00:16.000 --> 00:00:18.000
May I take a picture of you and your little boy?
我可以替你和你的小男孩拍张照片吗?
6
00:00:18.000 --> 00:00:19.000
What's it for?
是做什么用的?
7
00:00:19.000 --> 00:00:20.000
It's for a book.
是为一本书拍的
8
00:00:20.000 --> 00:00:21.000
You're writing a book?
你在写一本书吗?
9
00:00:21.400 --> 00:00:23.000
It's a book of pictures.
这是一本摄影集
10
00:00:23.000 --> 00:00:25.000
I call it Family Album, U.S.A.
我称之为《走遍美国》
11
00:00:25.000 --> 00:00:27.000
Oh, that's a nice idea.
噢 这想法不错