1 | import videojs from 'video.js';
|
2 |
|
3 | const defaultOptions = {
|
4 | errorInterval: 30,
|
5 | getSource(next) {
|
6 | const tech = this.tech({ IWillNotUseThisInPlugins: true });
|
7 | const sourceObj = tech.currentSource_ || this.currentSource();
|
8 |
|
9 | return next(sourceObj);
|
10 | }
|
11 | };
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | const initPlugin = function(player, options) {
|
21 | let lastCalled = 0;
|
22 | let seekTo = 0;
|
23 | const localOptions = videojs.mergeOptions(defaultOptions, options);
|
24 |
|
25 | player.ready(() => {
|
26 | player.trigger({type: 'usage', name: 'vhs-error-reload-initialized'});
|
27 | player.trigger({type: 'usage', name: 'hls-error-reload-initialized'});
|
28 | });
|
29 |
|
30 | |
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | const loadedMetadataHandler = function() {
|
37 | if (seekTo) {
|
38 | player.currentTime(seekTo);
|
39 | }
|
40 | };
|
41 |
|
42 | |
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 | const setSource = function(sourceObj) {
|
49 | if (sourceObj === null || sourceObj === undefined) {
|
50 | return;
|
51 | }
|
52 | seekTo = (player.duration() !== Infinity && player.currentTime()) || 0;
|
53 |
|
54 | player.one('loadedmetadata', loadedMetadataHandler);
|
55 |
|
56 | player.src(sourceObj);
|
57 | player.trigger({type: 'usage', name: 'vhs-error-reload'});
|
58 | player.trigger({type: 'usage', name: 'hls-error-reload'});
|
59 | player.play();
|
60 | };
|
61 |
|
62 | |
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 | const errorHandler = function() {
|
69 |
|
70 |
|
71 | if (Date.now() - lastCalled < localOptions.errorInterval * 1000) {
|
72 | player.trigger({type: 'usage', name: 'vhs-error-reload-canceled'});
|
73 | player.trigger({type: 'usage', name: 'hls-error-reload-canceled'});
|
74 | return;
|
75 | }
|
76 |
|
77 | if (!localOptions.getSource ||
|
78 | typeof localOptions.getSource !== 'function') {
|
79 | videojs.log.error('ERROR: reloadSourceOnError - The option getSource must be a function!');
|
80 | return;
|
81 | }
|
82 | lastCalled = Date.now();
|
83 |
|
84 | return localOptions.getSource.call(player, setSource);
|
85 | };
|
86 |
|
87 | |
88 |
|
89 |
|
90 |
|
91 |
|
92 | const cleanupEvents = function() {
|
93 | player.off('loadedmetadata', loadedMetadataHandler);
|
94 | player.off('error', errorHandler);
|
95 | player.off('dispose', cleanupEvents);
|
96 | };
|
97 |
|
98 | |
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 | const reinitPlugin = function(newOptions) {
|
105 | cleanupEvents();
|
106 | initPlugin(player, newOptions);
|
107 | };
|
108 |
|
109 | player.on('error', errorHandler);
|
110 | player.on('dispose', cleanupEvents);
|
111 |
|
112 |
|
113 |
|
114 | player.reloadSourceOnError = reinitPlugin;
|
115 | };
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 | const reloadSourceOnError = function(options) {
|
124 | initPlugin(this, options);
|
125 | };
|
126 |
|
127 | export default reloadSourceOnError;
|