-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMediaElement.js
222 lines (187 loc) · 6.77 KB
/
MediaElement.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
import React, { Component } from "react";
import "../../node_modules/hls.js/dist/hls.light.js";
//import "hls.js";
import "mediaelement";
// Import stylesheet and shims
//import "mediaelement/build/mediaelementplayer.min.css";
//import "mediaelement/build/mediaelement-flash-video.swf";
import PropTypes from "prop-types";
export default class MediaElement extends Component {
constructor(props) {
super(props);
this.state = { player: null, errorMode: false, srcBeingUpdated: false };
}
//state = {}
success(media, node, instance) {
// Your action when media was successfully loaded
//media.play();
console.log("MediaElement: " + media + " " + node + " " + instance);
let self = this;
media.addEventListener("error", function(err) {
// https://html.spec.whatwg.org/multipage/media.html#error-codes
// const unsigned short MEDIA_ERR_ABORTED = 1;
// const unsigned short MEDIA_ERR_NETWORK = 2;
// const unsigned short MEDIA_ERR_DECODE = 3;
// const unsigned short MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
if (self.state.player.src.slice(-1) !== "/") { // empty src gives the page url ending with "/". do no try alt codecs if there is empty src.
console.log("playback error: " + err.detail.target.error.code + " at url " + self.state.player.src);
self.setState({ errorMode: true });
self.props.onError(err);
} /*else {
console.log("playback error ignored");
}*/
/*if(err.detail.target.error.code === 2) {
console.log("mediaElement: network error. try restarting playback"); // for some streams, the playbacks resumes automatically
let correctSrc = media.src;
let player = self.state.player;
player.currentTime = 0;
player.src = "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAVFYAAFRWAAABAAgAZGF0YQAAAAA=";
self.setState({ player: player }, function() {
self.state.player.load();
let player = self.state.player;
player.src = correctSrc;
self.setState({ player: player }, function() {
self.state.player.play();
});
});
} else {*/
//}
});
media.addEventListener("play", function() {
console.log("playback started");
});
media.addEventListener("pause", function() {
console.log("playback paused, srcBeingUpdated=" + self.state.srcBeingUpdated);
if (!self.state.srcBeingUpdated) {
self.props.onPause();
}
});
}
error(media) {
// Your action when media had an error loading
console.log("MediaElement: error " + media);
}
UNSAFE_componentWillReceiveProps(nextProps) { // TODO update this
if (this.state.player && this.props.url !== nextProps.url) {
this.setState({ srcBeingUpdated: true }, function() {
let player = this.state.player;
/*if (!nextProps.url) {
this.state.player.pause();
}*/
player.currentTime = 0;
player.src = nextProps.url;
let self = this;
this.setState({ player: player, errorMode: false }, function() {
if (self.state.player.src && self.state.player.src.slice(-1) !== "/") {
//self.state.player.load();
let player = self.state.player;
player.load();
player.options.startVolume = nextProps.volume;
player.volume = nextProps.volume;
self.state.player.play();
self.setState({ player: player, srcBeingUpdated: false});
} else {
this.setState({ srcBeingUpdated: false });
//console.log("MediaPlayer: new props with empty url, do not play");
}
});
console.log("MediaElement: url updated to " + nextProps.url);
});
} else if (!this.state.player && this.props.url !== nextProps.url) {
console.log("MediaElement: warn: url update but no player yet");
}
if (this.state.player && this.props.volume !== nextProps.volume) {
let player = this.state.player;
player.volume = nextProps.volume;
this.setState({ player: player });
console.log("MediaElement: volume updated to " + nextProps.volume);
} else if (!this.state.player && this.props.volume !== nextProps.volume) {
console.log("MediaElement: warn: volume update but no player yet");
}
}
render() {
//const props = this.props;
//const source = JSON.parse(this.props.source);
//const tracks = JSON.parse(props.tracks);
//const sourceTags = [];
//const tracksTags = [];
/*for (let i = 0, total = sources.length; i < total; i++) {
const source = sources[i];
sourceTags.push(`<source src="${source.src}" type="${source.type}">`);
}
for (let i = 0, total = tracks.length; i < total; i++) {
const track = tracks[i];
tracksTags.push(`<track src="${track.src}" kind="${track.kind}" srclang="${track.lang}"${(track.label ? ` label=${track.label}` : "")}>`);
}
const mediaBody = `${sourceTags.join("\n")}${tracksTags.join("\n")}`;*/
/*const mediaHtml = props.mediaType === "video" ?
`<video id="${props.id}" width="${props.width}" height="${props.height}"${(props.poster ? ` poster=${props.poster}` : "")}
${(props.controls ? " controls" : "")}${(props.preload ? ` preload="${props.preload}"` : "")}>
${mediaBody}
</video>` :
`<audio id="${props.id}" width="${props.width}" controls>
${mediaBody}
</audio>`
;
return (<div dangerouslySetInnerHTML={{__html: mediaHtml}}></div>);*/
return (
<audio id={this.props.id} width={this.props.width}>
<source src={this.props.url} />
</audio>
);
}
componentDidMount() {
const {MediaElementPlayer} = window;
if (!MediaElementPlayer) {
return;
}
const options = Object.assign({}, JSON.parse(this.props.options), {
// Read the Notes below for more explanation about how to set up the path for shims
pluginPath: "./static/media/",
startVolume: this.props.volume,
success: (media, node, instance) => this.success(media, node, instance),
error: (media, node) => this.error(media, node)
});
let player = new MediaElementPlayer(this.props.id, options);
window.meplayer = player;
player.volume = this.props.volume;
//if (this.props.url) player.play();
this.setState({player: player });
}
componentWillUnmount() {
if (this.state.player) {
this.state.player.remove();
this.setState({player: null});
}
}
}
MediaElement.propTypes = {
id: PropTypes.string.isRequired,
//mediaType: PropTypes.string.isRequired,
//preload: PropTypes.string.isRequired,
//controls: PropTypes.bool.isRequired,
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
//poster: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
//type: PropTypes.string.isRequired,
options: PropTypes.string.isRequired,
volume: PropTypes.number,
onError: PropTypes.func.isRequired,
onPause: PropTypes.func.isRequired,
//tracks: PropTypes.string.isRequired
};
/* usaqe
<MediaElement
id="player1"
mediaType="audio"
preload="none"
controls={false}
width={640}
height={360}
poster=""
sources={JSON.stringify(this.state.sources)}
options={"{}"}
tracks={"{}"} />
);
*/