Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop all react-youtube videos onSlide with react-image-gallery?

Tags:

reactjs

EDIT: SOLVED

I've been stuck on this one all day and if someone have an idea it would be greatly appreciated!

So I'm using react-image-gallery and react-youtube to build a video carousel and my problem is that the YouTube-component is rendering as many times as the amount of videos I have, so I have multiple 'players' (some sort of objects that can utilize the YouTube-methods (playVideo etc.)).

What I've tried in the code below is to push every player-object into an array, so player in state is an array of these objects, which seems to work fine (there is probably a better way to do it though). I've then tried to loop through this array in the _onSlide()-method to stop all videos when I slide to the next video in the gallery, but absoluteley nothing is happening.

Anyway, I want to make the current video stop when I slide to the next video so that only one video can play at a time.

import React, { Component } from 'react';
import { Card, Header, Modal } from 'semantic-ui-react';
import ImageGallery from 'react-image-gallery';
import YouTube from 'react-youtube';

export default class VideoCard extends Component {
  constructor(props) {
    super(props);
    this.state = {
      open: false,
      showPlayButton: true,
      showGalleryPlayButton: false,
      showFullscreenButton: true,
      showGalleryFullscreenButton: false,
      player: []
    };
    this.openModal = this.openModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
    this._renderVideo = this._renderVideo.bind(this);
    this._onSlide = this._onSlide.bind(this);
    this._onReady = this._onReady.bind(this);
  }

  _onReady(event) {
    const player = this.state.player;
    player.push(event.target);
    this.setState({
      player: player
    });
  }

  openModal() {
    this.setState({ open: true });
  }

  closeModal() {
    this.setState({ open: false, player: [] });
  }

   _renderVideo(item) {
    const opts = {
      height: '480',
      width: '100%'
    };
    return (
      <div className='image-gallery-image'>
        <div className='video-wrapper'>
          <YouTube videoId={item.embedUrl} opts={opts} onReady={this._onReady}/>
        </div>
      </div>
    );
  }

   _onSlide() {
    //This does nothing
    for (let i = 0; i < this.state.player; i++) {
      console.log(this.state.player[i]);
      this.state.player[i].pauseVideo();  
    }
  }

  render() {
    const { image, header, id, arr, index } = this.props;
    return (
      <div>
        <Card image={image} header={header} onClick={this.openModal}/>
        <Modal size='small' basic open={this.state.open} onClose={this.closeModal} closeIcon='close'>
          <ImageGallery
            items={arr}
            startIndex={index}
            showPlayButton={this.state.showPlayButton && this.state.showGalleryPlayButton}
            showFullscreenButton={this.state.showFullscreenButton && this.state.showGalleryFullscreenButton}
            onSlide={this._onSlide}
            infinite={false}
            renderItem={this._renderVideo}
          />
        </Modal>
      </div>
    );
  }
}
like image 541
Jimmy Höglund Avatar asked Jan 30 '26 14:01

Jimmy Höglund


1 Answers

Shortly after I posted I figured it out. I changed the for-loop to an arrow function forEach and it worked!

onSlide() {
  this.state.player.forEach((player) => {
    player.pauseVideo();
  });
}
like image 137
Jimmy Höglund Avatar answered Feb 02 '26 05:02

Jimmy Höglund