Skip to content

Commit

Permalink
Add proper mute support to fix autoplay
Browse files Browse the repository at this point in the history
  • Loading branch information
seniorapple committed May 13, 2018
1 parent 2af4956 commit 5f19643
Show file tree
Hide file tree
Showing 13 changed files with 107 additions and 20 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ For platforms like [Meteor](https://www.meteor.com) without direct use of `npm`
* If you are using `npm` and need to support [browsers without `Promise`](http://caniuse.com/#feat=promises) you will need a [`Promise` polyfill](https://github.com/stefanpenner/es6-promise).
* To support IE11 you will need to use [`babel-polyfill`](https://babeljs.io/docs/usage/polyfill) or a similar ES2015+ polyfill.

#### Autoplay

As of Chrome 66, [videos must be `muted` in order to play automatically](https://www.theverge.com/2018/3/22/17150870/google-chrome-autoplay-videos-sound-mute-update). Some players, like Facebook, cannot be unmuted until the user interacts with the video, so you may want to enable `controls` to allow users to unmute videos themselves.

### Props

Prop | Description | Default
Expand Down
22 changes: 14 additions & 8 deletions src/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,18 @@ export default class Player extends Component {
if (playing && !nextProps.playing && this.isPlaying) {
this.player.pause()
}
if (nextProps.volume !== null) {
if (volume !== nextProps.volume && !nextProps.muted) {
this.player.setVolume(nextProps.volume)
}
if (muted !== nextProps.muted) {
this.player.setVolume(nextProps.muted ? 0 : nextProps.volume)
if (volume !== nextProps.volume && nextProps.volume !== null) {
this.player.setVolume(nextProps.volume)
}
if (muted !== nextProps.muted) {
if (nextProps.muted) {
this.player.mute()
} else {
this.player.unmute()
if (nextProps.volume !== null) {
// Set volume next tick to fix a bug with DailyMotion
setTimeout(() => this.player.setVolume(nextProps.volume))
}
}
}
if (playbackRate !== nextProps.playbackRate && this.player.setPlaybackRate) {
Expand Down Expand Up @@ -121,8 +127,8 @@ export default class Player extends Component {
this.isLoading = false
const { onReady, playing, volume, muted } = this.props
onReady()
if (muted || volume !== null) {
this.player.setVolume(muted ? 0 : volume)
if (!muted && volume !== null) {
this.player.setVolume(volume)
}
if (playing) {
this.player.play()
Expand Down
7 changes: 7 additions & 0 deletions src/players/DailyMotion.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export class DailyMotion extends Component {
params: {
controls: controls,
autoplay: this.props.playing,
mute: this.props.muted,
start: parseStartTime(url),
origin: window.location.origin,
...config.dailymotion.params
Expand Down Expand Up @@ -74,6 +75,12 @@ export class DailyMotion extends Component {
setVolume (fraction) {
this.callPlayer('setVolume', fraction)
}
mute = () => {
this.callPlayer('setMuted', true)
}
unmute = () => {
this.callPlayer('setMuted', false)
}
getDuration () {
return this.player.duration || null
}
Expand Down
17 changes: 12 additions & 5 deletions src/players/Facebook.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ export class Facebook extends Component {
this.player.subscribe('finishedPlaying', this.props.onEnded)
this.player.subscribe('startedBuffering', this.props.onBuffer)
this.player.subscribe('error', this.props.onError)
this.callPlayer('unmute')
if (!this.props.muted) {
// Player is muted by default
this.callPlayer('unmute')
}
this.props.onReady()
}
})
Expand All @@ -54,11 +57,14 @@ export class Facebook extends Component {
this.callPlayer('seek', seconds)
}
setVolume (fraction) {
if (fraction !== 0) {
this.callPlayer('unmute')
}
this.callPlayer('setVolume', fraction)
}
mute = () => {
this.callPlayer('mute')
}
unmute = () => {
this.callPlayer('unmute')
}
getDuration () {
return this.callPlayer('getDuration')
}
Expand All @@ -80,8 +86,9 @@ export class Facebook extends Component {
id={this.playerID}
className='fb-video'
data-href={this.props.url}
data-autoplay={this.props.playing ? 'true' : 'false'}
data-allowfullscreen='true'
data-controls={!this.props.controls ? 'false' : undefined}
data-controls={this.props.controls ? 'true' : 'false'}
/>
)
}
Expand Down
14 changes: 11 additions & 3 deletions src/players/FilePlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ export class FilePlayer extends Component {
setVolume (fraction) {
this.player.volume = fraction
}
mute = () => {
this.player.muted = true
}
unmute = () => {
this.player.muted = false
}
setPlaybackRate (rate) {
this.player.playbackRate = rate
}
Expand Down Expand Up @@ -185,20 +191,22 @@ export class FilePlayer extends Component {
this.player = player
}
render () {
const { url, loop, controls, config, width, height } = this.props
const { url, playing, loop, controls, muted, config, width, height } = this.props
const useAudio = this.shouldUseAudio(this.props)
const Element = useAudio ? 'audio' : 'video'
const style = {
width: !width || width === 'auto' ? width : '100%',
height: !height || height === 'auto' ? height : '100%'
width: width === 'auto' ? width : '100%',
height: height === 'auto' ? height : '100%'
}
return (
<Element
ref={this.ref}
src={this.getSource(url)}
style={style}
preload='auto'
autoPlay={playing}
controls={controls}
muted={muted}
loop={loop}
{...config.file.attributes}>
{url instanceof Array &&
Expand Down
6 changes: 6 additions & 0 deletions src/players/Mixcloud.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ export class Mixcloud extends Component {
setVolume (fraction) {
// No volume support
}
mute = () => {
// No volume support
}
unmute = () => {
// No volume support
}
getDuration () {
return this.duration
}
Expand Down
8 changes: 8 additions & 0 deletions src/players/SoundCloud.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ export class SoundCloud extends Component {
setVolume (fraction) {
this.callPlayer('setVolume', fraction * 100)
}
mute = () => {
this.setVolume(0)
}
unmute = () => {
if (this.props.volume !== null) {
this.setVolume(this.props.volume)
}
}
getDuration () {
return this.duration
}
Expand Down
9 changes: 9 additions & 0 deletions src/players/Streamable.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export class Streamable extends Component {
this.secondsLoaded = this.duration * percent
}
})
if (this.props.muted) {
this.player.mute()
}
}, this.props.onError)
}
play () {
Expand All @@ -52,6 +55,12 @@ export class Streamable extends Component {
setVolume (fraction) {
this.callPlayer('setVolume', fraction * 100)
}
mute = () => {
this.callPlayer('mute')
}
unmute = () => {
this.callPlayer('unmute')
}
getDuration () {
return this.duration
}
Expand Down
7 changes: 7 additions & 0 deletions src/players/Twitch.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class Twitch extends Component {
width: '100%',
playsinline: playsinline,
autoplay: this.props.playing,
muted: this.props.muted,
...config.twitch.options
})
const { READY, PLAY, PAUSE, ENDED } = Twitch.Player
Expand All @@ -60,6 +61,12 @@ export class Twitch extends Component {
setVolume (fraction) {
this.callPlayer('setVolume', fraction)
}
mute = () => {
this.callPlayer('setMuted', true)
}
unmute = () => {
this.callPlayer('setMuted', false)
}
getDuration () {
return this.callPlayer('getDuration')
}
Expand Down
10 changes: 10 additions & 0 deletions src/players/Vimeo.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export class Vimeo extends Component {
this.player = new Vimeo.Player(this.container, {
...this.props.config.vimeo.playerOptions,
url,
autoplay: this.props.playing,
muted: this.props.muted,
loop: this.props.loop
})
this.player.ready().then(() => {
Expand Down Expand Up @@ -69,6 +71,14 @@ export class Vimeo extends Component {
setVolume (fraction) {
this.callPlayer('setVolume', fraction)
}
mute = () => {
this.setVolume(0)
}
unmute = () => {
if (this.props.volume !== null) {
this.setVolume(this.props.volume)
}
}
getDuration () {
return this.duration
}
Expand Down
11 changes: 10 additions & 1 deletion src/players/Wistia.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ export class Wistia extends Component {
return url && url.match(MATCH_URL)[1]
}
load (url) {
const { controls, onReady, onPlay, onPause, onSeek, onEnded, config } = this.props
const { playing, muted, controls, onReady, onPlay, onPause, onSeek, onEnded, config } = this.props
getSDK(SDK_URL, SDK_GLOBAL).then(() => {
window._wq = window._wq || []
window._wq.push({
id: this.getID(url),
options: {
autoPlay: playing,
silentAutoPlay: 'allow',
muted: muted,
controlsVisibleOnLoad: controls,
...config.wistia.options
},
Expand Down Expand Up @@ -52,6 +55,12 @@ export class Wistia extends Component {
setVolume (fraction) {
this.callPlayer('volume', fraction)
}
mute = () => {
this.callPlayer('mute')
}
unmute = () => {
this.callPlayer('unmute')
}
setPlaybackRate (rate) {
this.callPlayer('playbackRate', rate)
}
Expand Down
10 changes: 9 additions & 1 deletion src/players/YouTube.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class YouTube extends Component {

callPlayer = callPlayer
load (url, isReady) {
const { playsinline, controls, config, onError } = this.props
const { playing, muted, playsinline, controls, config, onError } = this.props
const id = url && url.match(MATCH_URL)[1]
if (isReady) {
this.player.cueVideoById({
Expand All @@ -31,6 +31,8 @@ export class YouTube extends Component {
height: '100%',
videoId: id,
playerVars: {
autoplay: playing ? 1 : 0,
mute: muted ? 1 : 0,
controls: controls ? 1 : 0,
start: parseStartTime(url),
origin: window.location.origin,
Expand Down Expand Up @@ -70,6 +72,12 @@ export class YouTube extends Component {
setVolume (fraction) {
this.callPlayer('setVolume', fraction * 100)
}
mute = () => {
this.callPlayer('mute')
}
unmute = () => {
this.callPlayer('unMute')
}
setPlaybackRate (rate) {
this.callPlayer('setPlaybackRate', rate)
}
Expand Down
2 changes: 0 additions & 2 deletions src/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ export const defaultProps = {
},
youtube: {
playerVars: {
autoplay: 0,
playsinline: 1,
showinfo: 0,
rel: 0,
Expand All @@ -115,7 +114,6 @@ export const defaultProps = {
vimeo: {
playerOptions: {
autopause: false,
autoplay: false,
byline: false,
portrait: false,
title: false
Expand Down

0 comments on commit 5f19643

Please sign in to comment.