Skip to content

Commit 35b488f

Browse files
committed
Merge pull request #17 from mderrick/videomethodsapi
Expose React media events
2 parents 659812f + dfd01a9 commit 35b488f

File tree

3 files changed

+56
-26
lines changed

3 files changed

+56
-26
lines changed

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,17 @@ import { default as Video, Controls, Play, Mute, Seek, Fullscreen, Time, Overlay
4747

4848
### Simple Usage
4949

50-
Use normal HTML5 `<video>` markup with all the standard [html attributes](https://developer.mozilla.org/en/docs/Web/HTML/Element/video):
50+
Use normal HTML5 `<video>` markup with all the standard [html attributes](https://developer.mozilla.org/en/docs/Web/HTML/Element/video) and supported [React media events](https://facebook.github.io/react/docs/events.html#media-events):
5151

5252
```js
5353
import Video from 'react-html5video';
5454
render() {
5555
return (
56-
<Video controls autoPlay loop muted poster="http://sourceposter.jpg">
56+
<Video controls autoPlay loop muted
57+
poster="http://sourceposter.jpg"
58+
onCanPlayThrough={() => {
59+
// Do stuff
60+
}}>
5761
<source src="http://sourcefile.webm" type="video/webm" />
5862
</Video>
5963
);

demo/src/components/index/main/Main.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import ReactDOM from 'react-dom';
23
import Button from './../../button/button';
34
import browserStackLogo from './../../../../browserstack.png';
45
import {default as Video, Controls, Overlay} from './../../../../../src/components/video/video';
@@ -72,14 +73,21 @@ var Main = React.createClass({
7273
this.refs.video.setVolume(this._volumeInput.valueAsNumber);
7374
},
7475

76+
onProgress() {
77+
var el = ReactDOM.findDOMNode(this.refs.video).getElementsByTagName('video')[0];
78+
this.setState({
79+
percentageLoaded: el.buffered.length && el.buffered.end(el.buffered.length - 1) / el.duration * 100
80+
});
81+
},
82+
7583
render() {
7684
return (
7785
<div className="main">
7886
<h1 className="main__title">
7987
<span className="main__react-logo"></span> React HTML5 Video
8088
</h1>
8189
<div className="main__video">
82-
<Video controls autoPlay loop muted ref="video">
90+
<Video controls autoPlay loop muted ref="video" onProgress={this.onProgress}>
8391
<source src={videos[this.state.videoId]} type="video/mp4" />
8492
<Overlay />
8593
<Controls />
@@ -94,6 +102,8 @@ var Main = React.createClass({
94102
<li><Button active={this.state.videoId === 2} onClick={this.showVideo.bind(this, 2)}>3</Button></li>
95103
<li><Button active={this.state.videoId === 3} onClick={this.showVideo.bind(this, 3)}>Unsupported Source</Button></li>
96104
</ul>
105+
<h2 className="main__h2">Video Loaded</h2>
106+
{this.state.percentageLoaded}%
97107
</div>
98108
<div className="main__col2">
99109
<h2 className="main__h2">Video API</h2>

src/components/video/Video.js

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,32 @@ import PureRenderMixin from 'react-addons-pure-render-mixin';
1111
import throttle from 'lodash.throttle';
1212
import copy from './../../assets/copy';
1313

14+
var EVENTS = [
15+
'onAbort',
16+
'onCanPlay',
17+
'onCanPlayThrough',
18+
'onDurationChange',
19+
'onEmptied',
20+
'onEncrypted',
21+
'onEnded',
22+
'onError',
23+
'onLoadedData',
24+
'onLoadedMetadata',
25+
'onLoadStart',
26+
'onPause',
27+
'onPlay',
28+
'onPlaying',
29+
'onProgress',
30+
'onRateChange',
31+
'onSeeked',
32+
'onSeeking',
33+
'onStalled',
34+
'onSuspend',
35+
'onTimeUpdate',
36+
'onVolumeChange',
37+
'onWaiting'
38+
];
39+
1440
var Video = React.createClass({
1541

1642
propTypes: {
@@ -55,6 +81,18 @@ var Video = React.createClass({
5581
// Also bind 'this' as we call _updateStateFromVideo outside
5682
// of Reacts synthetic events as well.
5783
this._updateStateFromVideo = throttle(this.updateStateFromVideo, 100).bind(this);
84+
// Set up all React media events and call method
85+
// on props if provided.
86+
this.mediaEventProps = EVENTS.reduce((p, c) => {
87+
p[c] = () => {
88+
if (c in this.props && typeof this.props[c] === 'function') {
89+
// A prop exists for this mediaEvent, call it.
90+
this.props[c]();
91+
}
92+
this._updateStateFromVideo();
93+
};
94+
return p;
95+
}, {});
5896
},
5997

6098
/**
@@ -314,29 +352,7 @@ var Video = React.createClass({
314352
// We have throttled `_updateStateFromVideo` so listen to
315353
// every available Media event that React allows and
316354
// infer the Video state in that method from the Video properties.
317-
onAbort={this._updateStateFromVideo}
318-
onCanPlay={this._updateStateFromVideo}
319-
onCanPlayThrough={this._updateStateFromVideo}
320-
onDurationChange={this._updateStateFromVideo}
321-
onEmptied={this._updateStateFromVideo}
322-
onEncrypted={this._updateStateFromVideo}
323-
onEnded={this._updateStateFromVideo}
324-
onError={this._updateStateFromVideo}
325-
onLoadedData={this._updateStateFromVideo}
326-
onLoadedMetadata={this._updateStateFromVideo}
327-
onLoadStart={this._updateStateFromVideo}
328-
onPause={this._updateStateFromVideo}
329-
onPlay={this._updateStateFromVideo}
330-
onPlaying={this._updateStateFromVideo}
331-
onProgress={this._updateStateFromVideo}
332-
onRateChange={this._updateStateFromVideo}
333-
onSeeked={this._updateStateFromVideo}
334-
onSeeking={this._updateStateFromVideo}
335-
onStalled={this._updateStateFromVideo}
336-
onSuspend={this._updateStateFromVideo}
337-
onTimeUpdate={this._updateStateFromVideo}
338-
onVolumeChange={this._updateStateFromVideo}
339-
onWaiting={this._updateStateFromVideo}>
355+
{...this.mediaEventProps}>
340356
{this.renderSources()}
341357
</video>
342358
{controls ? this.renderControls() : ''}

0 commit comments

Comments
 (0)