Comparing version
@@ -1,18 +0,7 @@ | ||
declare module "srt-webvtt" { | ||
class WebVTTConverter { | ||
constructor(resource: Blob); | ||
public blobToBuffer(): Promise<Uint8Array | string>; | ||
public static blobToString( | ||
blob: Blob, | ||
success: (result: string) => void, | ||
fail: () => void | ||
): void; | ||
public static toVTT(utf8str: string): string; | ||
public static toTypedArray(str: string): Uint8Array; | ||
public getURL(): Promise<string>; | ||
public release(): void; | ||
} | ||
export default WebVTTConverter; | ||
} | ||
export declare const moduleName = "toWebVTT"; | ||
/** | ||
* @param resource | ||
* @returns Promise<string> | ||
*/ | ||
declare const toWebVTT: (resource: Blob) => Promise<string>; | ||
export default toWebVTT; |
240
lib/index.js
@@ -1,115 +0,127 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var WebVTTConverter = function () { | ||
function WebVTTConverter(resource) { | ||
_classCallCheck(this, WebVTTConverter); | ||
this.resource = resource; | ||
} | ||
_createClass(WebVTTConverter, [{ | ||
key: 'blobToBuffer', | ||
value: function blobToBuffer() { | ||
var _this = this; | ||
return new Promise(function (resolve, reject) { | ||
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.moduleName = void 0; | ||
exports.moduleName = 'toWebVTT'; | ||
/** | ||
* @param blob | ||
* @param readAs | ||
* @returns Promise<ArrayBuffer> | ||
*/ | ||
var blobToBufferOrString = function (blob, readAs) { | ||
return new Promise(function (resolve, reject) { | ||
var reader = new FileReader(); | ||
reader.addEventListener('loadend', function (event) { | ||
var buf = event.target.result; | ||
resolve(new Uint8Array(buf)); | ||
}); | ||
reader.addEventListener('error', function () { | ||
return reject('Error while reading the Blob object'); | ||
}); | ||
reader.readAsArrayBuffer(_this.resource); | ||
}); | ||
} | ||
/** | ||
* @param {*} blob | ||
* @param {*} success | ||
* @param {*} fail | ||
*/ | ||
}, { | ||
key: 'getURL', | ||
value: function getURL() { | ||
var _this2 = this; | ||
return new Promise(function (resolve, reject) { | ||
if (!(_this2.resource instanceof Blob)) return reject('Expecting resource to be a Blob but something else found.'); | ||
if (!FileReader) return reject('No FileReader constructor found'); | ||
if (!TextDecoder) return reject('No TextDecoder constructor found'); | ||
return WebVTTConverter.blobToString(_this2.resource, function (decoded) { | ||
var vttString = 'WEBVTT FILE\r\n\r\n'; | ||
var text = vttString.concat(WebVTTConverter.toVTT(decoded)); | ||
var blob = new Blob([text], { type: 'text/vtt' }); | ||
_this2.objectURL = URL.createObjectURL(blob); | ||
return resolve(_this2.objectURL); | ||
}, function () { | ||
_this2.blobToBuffer().then(function (buffer) { | ||
var utf8str = new TextDecoder('utf-8').decode(buffer); | ||
var vttString = 'WEBVTT FILE\r\n\r\n'; | ||
var text = vttString.concat(WebVTTConverter.toVTT(utf8str)); | ||
var blob = new Blob([text], { type: 'text/vtt' }); | ||
_this2.objectURL = URL.createObjectURL(blob); | ||
return resolve(_this2.objectURL); | ||
}); | ||
}); | ||
}); | ||
} | ||
}, { | ||
key: 'release', | ||
value: function release() { | ||
URL.createObjectURL(this.objectURL); | ||
} | ||
}], [{ | ||
key: 'blobToString', | ||
value: function blobToString(blob, success, fail) { | ||
var reader = new FileReader(); | ||
reader.addEventListener('loadend', function (event) { | ||
var text = event.target.result; | ||
success(text); | ||
}); | ||
reader.addEventListener('error', function () { | ||
return fail(); | ||
}); | ||
reader.readAsText(blob); | ||
} | ||
/** | ||
* @param {*} utf8str | ||
*/ | ||
}, { | ||
key: 'toVTT', | ||
value: function toVTT(utf8str) { | ||
return utf8str.replace(/\{\\([ibu])\}/g, '</$1>').replace(/\{\\([ibu])1\}/g, '<$1>').replace(/\{([ibu])\}/g, '<$1>').replace(/\{\/([ibu])\}/g, '</$1>').replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g, '$1.$2').concat('\r\n\r\n'); | ||
} | ||
/** | ||
* @param {*} str | ||
*/ | ||
}, { | ||
key: 'toTypedArray', | ||
value: function toTypedArray(str) { | ||
var result = []; | ||
str.split('').forEach(function (each) { | ||
result.push(parseInt(each.charCodeAt(), 16)); | ||
}); | ||
return Uint8Array.from(result); | ||
} | ||
}]); | ||
return WebVTTConverter; | ||
}(); | ||
window.WebVTTConverter = WebVTTConverter; | ||
exports.default = WebVTTConverter; | ||
/** | ||
* @param event | ||
*/ | ||
var loadedCb = function (event) { | ||
var buf = event.target.result; | ||
reader.removeEventListener('loadend', loadedCb); | ||
resolve(readAs !== 'string' ? new Uint8Array(buf) : buf); | ||
}; | ||
var errorCb = function () { | ||
reader.removeEventListener('error', errorCb); | ||
reject(new Error(exports.moduleName + ": Error while reading the Blob object")); | ||
}; | ||
reader.addEventListener('loadend', loadedCb); | ||
reader.addEventListener('error', errorCb); | ||
if (readAs !== 'string') { | ||
reader.readAsArrayBuffer(blob); | ||
} | ||
else { | ||
reader.readAsText(blob); | ||
} | ||
}); | ||
}; | ||
/** | ||
* @param text | ||
* @returns ObjectURL | ||
*/ | ||
var blobToURL = function (text) { return URL | ||
.createObjectURL(new Blob([text], { type: 'text/vtt' })); }; | ||
/** | ||
* @param utf8str | ||
* @returns string | ||
*/ | ||
var toVTT = function (utf8str) { return utf8str | ||
.replace(/\{\\([ibu])\}/g, '</$1>') | ||
.replace(/\{\\([ibu])1\}/g, '<$1>') | ||
.replace(/\{([ibu])\}/g, '<$1>') | ||
.replace(/\{\/([ibu])\}/g, '</$1>') | ||
.replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g, '$1.$2') | ||
.concat('\r\n\r\n'); }; | ||
/** | ||
* @param resource | ||
* @returns Promise<string> | ||
*/ | ||
var toWebVTT = function (resource) { return __awaiter(void 0, void 0, void 0, function () { | ||
var text, vttString, buffer, e_1, buffer, decode; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!(FileReader)) { | ||
throw (new Error(exports.moduleName + ": No FileReader constructor found")); | ||
} | ||
if (!TextDecoder) { | ||
throw (new Error(exports.moduleName + ": No TextDecoder constructor found")); | ||
} | ||
if (!(resource instanceof Blob)) { | ||
throw new Error(exports.moduleName + ": Expecting resource to be a Blob but something else found."); | ||
} | ||
vttString = 'WEBVTT FILE\r\n\r\n'; | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 5]); | ||
return [4 /*yield*/, blobToBufferOrString(resource, 'string')]; | ||
case 2: | ||
buffer = _a.sent(); | ||
text = vttString.concat(toVTT(buffer)); | ||
return [3 /*break*/, 5]; | ||
case 3: | ||
e_1 = _a.sent(); | ||
return [4 /*yield*/, blobToBufferOrString(resource, 'buffer')]; | ||
case 4: | ||
buffer = _a.sent(); | ||
decode = new TextDecoder('utf-8').decode(buffer); | ||
text = vttString.concat(toVTT(decode)); | ||
return [3 /*break*/, 5]; | ||
case 5: return [2 /*return*/, Promise.resolve(blobToURL(text))]; | ||
} | ||
}); | ||
}); }; | ||
exports.default = toWebVTT; |
{ | ||
"name": "srt-webvtt", | ||
"version": "1.3.2", | ||
"version": "2.0.0", | ||
"description": "Convert SRT format subtitle to WebVTT on the fly over HTML5 environment", | ||
@@ -11,5 +11,5 @@ "main": "lib/index.js", | ||
"scripts": { | ||
"test": "./node_modules/.bin/eslint ./index.js", | ||
"start": "webpack-dev-server", | ||
"build": "babel ./index.js --stage 2 -d ./lib/ && webpack -p ./index.js ./umd/index.min.js && cp index.d.ts lib/index.d.ts", | ||
"test": "./node_modules/.bin/jest", | ||
"lint": "./node_modules/.bin/eslint ./index.js", | ||
"build": "rm -rf lib && tsc", | ||
"minor": "npm version minor && npm publish", | ||
@@ -50,8 +50,3 @@ "major": "npm version major && npm publish", | ||
"devDependencies": { | ||
"babel-core": "^6.26.0", | ||
"babel-eslint": "^8.2.1", | ||
"babel-loader": "^7.1.2", | ||
"babel-preset-env": "^1.6.1", | ||
"babel-preset-es2015": "^6.24.1", | ||
"babel-preset-stage-2": "^6.24.1", | ||
"@types/jest": "^27.0.2", | ||
"eslint": "^4.15.0", | ||
@@ -62,6 +57,6 @@ "eslint-config-airbnb": "^16.1.0", | ||
"eslint-plugin-react": "^7.5.1", | ||
"html-webpack-plugin": "^2.30.1", | ||
"webpack": "^3.10.0", | ||
"webpack-dev-server": "^2.11.0" | ||
"jest": "^27.3.1", | ||
"ts-jest": "^27.0.7", | ||
"typescript": "^4.4.4" | ||
} | ||
} |
@@ -0,11 +1,9 @@ | ||
<h2 align="left"> Convert and generate URL of WebVTT from .srt subtitle file on the fly over Browser/HTML5 environment</h2> | ||
<h2 align="left"> Convert and generate ObjectURL of WebVTT from srt format subtitle on the fly over HTML5 environment</h2> | ||
HTMLMediaElement/Video doesn't support `.srt` (SubRip Track) format subtitle as its `<track>` source - in order to show captions of your video track either you have to convert the SRT file to WebVTT or write it on your own. Because `<track src="VALID URL SCHEME">` requires a valid URL of `.vtt` (Web Video Text Track) formated subtitle track. | ||
This library will let you do this on the fly and will give you an URL to set the source of caption track. | ||
HTMLMediaElement/Video doesn't support ```.srt``` (SubRip Track) format subtitle as its ```<track>``` source - in order to show captions of your video track either you have to convert the SRT file to WebVTT or write it on your own. Because ```<track src="VALID URL SCHEME">``` requires a valid URL of ```.vtt``` (Web Video Text Track) formated subtitle track. | ||
This library will let you do this on the fly and will give you an URL to set the source of caption track. | ||
<p align="center"> | ||
<a href="https://www.npmjs.org/package/srt-webvtt"><img src="https://img.shields.io/npm/v/srt-webvtt.svg?style=flat-square" /></a> | ||
<a href="https://travis-ci.org/imshaikot/srt-webvtt"><img src="https://api.travis-ci.org/imshaikot/srt-webvtt.svg" /></a> | ||
<a href="https://github.com/imshaikot/srt-webvtt/actions/workflows/node.js.yml"><img src="https://github.com/imshaikot/srt-webvtt/actions/workflows/node.js.yml/badge.svg" /></a> | ||
<a href="https://github.com/imshaikot/srt-webvtt/blob/master/LICENSE"> | ||
@@ -29,6 +27,2 @@ <img src="https://img.shields.io/github/license/imshaikot/srt-webvtt.svg"> | ||
``` | ||
OR umd builds are also available | ||
``` | ||
<script src="https://unpkg.com/srt-webvtt/umd/index.min.js"></script> | ||
``` | ||
@@ -41,7 +35,7 @@ ## Getting Started | ||
```js | ||
// Using ES6 | ||
import VTTConverter from 'srt-webvtt'; // This is a default export, so you don't have to worry about the import name | ||
// Using ES6 es-module | ||
import toWebVTT from "srt-webvtt"; // This is a default export, so you don't have to worry about the import name | ||
// Not using ES6 | ||
var VTTConverter = require('srt-webvtt'); | ||
// Not using ES6?? | ||
var toWebVTT = require("srt-webvtt"); | ||
``` | ||
@@ -51,11 +45,10 @@ | ||
When you're about to use ```HTMLMediaElement``` (example: ```<video>```) and you want to show caption on your video player - there's a native feature that will allow you to do that. | ||
See the official MDN article and tutorial of this ```<track>``` feature | ||
When you're using `HTMLMediaElement` (example: `<video>`) and you want to show caption on your video player - there's a native HTML Element that will allow us to do that. | ||
See the official MDN article and tutorial of this `<track>` feature | ||
<a href="https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Adding_captions_and_subtitles_to_HTML5_video"> Adding captions and subtitles to HTML5 video</a> | ||
But this feature is limited to WebVTT format and won't allow you to use SRT (very commonly used subtitle) | ||
So, this tiny library will take your ```.srt``` subtitle file or a ```Blob``` object and will give you converted ```.vtt``` file's valid Object URL that you can set as ```<track>```'s source. | ||
So, this tiny library will take your `.srt` subtitle file or a `Blob` object and will give you converted `.vtt` file's valid Object URL that you can set as `<track>`'s source. | ||
@@ -65,17 +58,14 @@ <h4>See the Example below:</h4> | ||
```js | ||
import VTTConverter from 'srt-webvtt'; | ||
import { default as toWebVTT } from "srt-webvtt"; | ||
const vttConverter = new VTTConverter(input.files[0]); // the constructor accepts a parameer of SRT subtitle blob/file object | ||
vttConverter | ||
.getURL() | ||
.then(function(url) { // Its a valid url that can be used further | ||
var track = document.getElementById('my-sub-track'); // Track element (which is child of a video element) | ||
var video = document.getElementById('my-video'); // Main video element | ||
track.src = url; // Set the converted URL to track's source | ||
video.textTracks[0].mode = 'show'; // Start showing subtitle to your track | ||
}) | ||
.catch(function(err) { | ||
console.error(err); | ||
}) | ||
try { | ||
const textTrackUrl = await toWebVTT(input.files[0]); // this function accepts a parameer of SRT subtitle blob/file object | ||
// It is a valid url that can be used as text track URL | ||
var track = document.getElementById("my-sub-track"); // Track element (which is child of a video element) | ||
var video = document.getElementById("my-video"); // Main video element | ||
track.src = textTrackUrl; // Set the converted URL to track's source | ||
video.textTracks[0].mode = "show"; // Start showing subtitle to your track | ||
} catch (e) { | ||
console.error(e.message); | ||
} | ||
``` | ||
@@ -85,11 +75,6 @@ | ||
```Constructor(Blob)``` The constructor must a valid Blob reference to a valid srt file | ||
`toWebVTT(file: Blob): Promise<string>` and this is it :) | ||
```getURL()``` resolves a promise with the converted subtitle's Object URL or rejects with appropriate error. | ||
```release()``` as long as you're done with the URL and subtitle you call this instance method to release the memory. | ||
## LICENSE | ||
MIT |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
11499
5.62%9
-35.71%134
14.53%76
-16.48%1
Infinity%