使用HTML5,您可以使用元素向视频添加标题。然而,只有vtt文件是官方支持的,而当前最流行的字幕格式是众所周知的srt格式。
因此,我没有将所有srt文件转换为vtt文件,而是编写了一个脚本,它将实时完成所有这些工作。没有任何手动转换。
使用脚本,可以将srt文件添加到元素中,如下所示:
脚本所做的基本工作如下
src。脚本本身非常简单和小,只有4kb的大小。我想知道我是否可以使脚本更小,如果我把代码写得很好。
document.addEventListener("DOMContentLoaded", function () {
/**
* Get all videos
*/
var videoElements = document.getElementsByTagName('video');
/**
* This function converts all srt's to vtt files
*/
function convertSrtToVtt()
{
/**
* Generate an unique identifier
*/
this.id = '_' + Math.random().toString(36).substr(2, 9);
/**
* All tracks assigned to current video element
*/
var tracks = document.querySelectorAll("#" + this.id + " track");
var subtitle = {
data:
{
track: {}
},
/**
* Load the file from url
*
* @param {object} track - DOM object
*/
load: function(track)
{
subtitle.track = track;
if(subtitle.isSrt(subtitle.track.src))
{
var client = new XMLHttpRequest();
client.open('GET', subtitle.track.src);
client.onreadystatechange = function()
{
subtitle.convert(client.responseText).then(
function (file)
{
/**
* Replace the srt file with the generated vtt file
*/
subtitle.track.src = file
}
);
}
client.send();
}
},
/**
* Converts the SRT string to a VTT formatted string
*
* @param {string} content - SRT string
* @return {object} promise - Returns a promise with the generated file as the return value
*/
convert: function(content)
{
var promise = new Promise(
function (resolve, reject)
{
/**
* Replace all (,) commas with (.) dots. Eg: 00:00:01,144 -> 00:00:01.144
*/
content = content.replace(/(\d+:\d+:\d+)+,(\d+)/g, '$1.$2');
content = "WEBVTT - Generated using SRT2VTT\r\n\r\n" + content;
/**
* Convert content to a file
*/
var blob = new Blob([content], {type: 'text/vtt'});
var file = window.URL.createObjectURL(blob);
resolve(file);
}
);
return promise;
},
isSrt: function(filename)
{
return filename.split('.').pop().toLowerCase() === 'srt' ? true : false;
},
isVTT: function(filename)
{
return filename.split('.').pop().toLowerCase() === 'vtt' ? true : false;
}
}
for(var i = 0;i < tracks.length;i++)
{
subtitle.load(tracks[i]);
}
}
for(var i = 0;i < videoElements.length;i++)
{
videoElements[i].addEventListener('loadstart', convertSrtToVtt);
}
});发布于 2019-02-21 21:46:37
您有104行代码,这些代码可以很容易地通过一些简单的功能来提高可读性。删除注释,同一行打开阻止{,并删除空行。这将代码减少到54行。
我看你对JS有点陌生
const。{放在同一行中。window是默认对象,您不需要使用它。你不是用它来做Blob (如new window.Blob( ),但是下一行你用它做URL,为什么?for(var i = 0;i < tracks.length;i++) {索引是不需要的,所以for(const track of tracks)或tracks.forEach(subtitle.load)会更好;substr,它在折旧的大清单上。使用substring或sliceload: function(track) {应该是load(track) {if和(之间的空间new Promise( function (resolve, reject) {没有语义意义,类似于new Promise(converted => {的东西会更贴切。return filename.split('.').pop().toLowerCase() === 'srt' ? true : false;与return filename.split('.').pop().toLowerCase() === 'srt';相同isSrt和isVTT添加到对象中。它们是通用的,可以在对象之外定义一次(BTW应该是isSrt还是isSRT,我不知道它代表什么,但是如果是首字母缩略词,那么它应该是大写?)id可以产生小于7个字符的字符串。例如(1/36).toString(36).substr(2, 9)会创建"1"而不是"1000000"id (冲突的可能性很大)的意义。subtitle的情况下创建它?subtitle: { data: { track: {}}...。我找不到任何参考资料。FetchAPI接口而不是XMLHttpRequest可以消除大量的膨胀,从而可以在一个页面中查看该过程,从而提高了可维护性、可读性,并减少了出现bug的可能性。
document.addEventListener("DOMContentLoaded", function () {
const isSrt = name => name.split(".").pop().toLowerCase() === "srt";
const convert = content => new Promise(converted => {
content = content.replace(/(\d+:\d+:\d+)+,(\d+)/g, "$1.$2");
content = "WEBVTT - Generated using SRT2VTT\r\n\r\n" + content;
converted(URL.createObjectURL(new Blob([content], {type: "text/vtt"})));
});
for (const vid of document.getElementsByTagName("video")) {
vid.addEventListener("loadstart", event => {
const tracks = [...event.target.querySelectorAll("track")];
tracks.forEach(track => {
if (isSrt(track.src)) {
const client = new XMLHttpRequest();
client.open("GET", track.src);
client.onreadystatechange = () => {
convert(client.responseText).then(file => track.src = file);
};
client.send();
}
});
}
}
});要支持遗留浏览器,您应该使用类似于巴贝尔的内容。请注意,这将不包括媒体textTrack支持,只有javascript
发布于 2019-02-21 22:49:26
破坏每个id元素的属性是意外的,也是不公平的。这可能会破坏页面(例如任何依赖于原始id的CSS规则)。
巨大的convertSrtToVtt()定义位于var videoElements定义和使用这些videoElements的循环之间。对于可读性来说,这是一个巨大的不必要的烦恼。
就我个人而言,我发现
/**
* Multi-line comments
*/妨碍可读性,尤指当注释适用于单个语句时。
isVTT函数从未使用过,应该删除。(请注意,它的大写与isSrt和convertSrtToVtt不一致。)
https://codereview.stackexchange.com/questions/213970
复制相似问题