1
votes

How do I make a self contained video player like jwplayer or the youtube video player? I know I can make a video player using the video tag along with some javascript and css, but how do I make so that you would only have to add a couple of lines of code to use it like jwplayer and youtube does?

What I have found out from looking at the jwplayer website is that they only have to include a couple of lines of javascript to use the player: https://support.jwplayer.com/articles/how-to-embed-a-jwplayer

With the youtube player you only have to put the video you want to use in a iframe? Why is the video only being displayed when using the iframe? According to this: https://www.w3schools.com/tags/tag_iframe.asp it's suppose to display the whole website not just the video player?

Code snippet from the jwplayer website:

<div id="myElement"></div>

<script type="text/javascript">
    var playerInstance = jwplayer("myElement");
    playerInstance.setup({
        file: "//example.com/uploads/myVideo.mp4",
        mediaid: "xxxxYYYY"

    });
</script>

How you embed youtube videos:

<iframe src="http://www.youtube.com/embed/W7qWa52k-nE"
width="560" height="315" frameborder="0" allowfullscreen></iframe>



How can I do this using only using html, css, and javascript?

1

1 Answers

2
votes

To begin with, the iframe on youtube displays the complete page well. But you can see that in the url, the complete page is not https://www.youtube.com/watch?v=W7qWa52k-nE (which display normal Youtube's page) but https://www.youtube.com/embed/W7qWa52k-nE (note the "embed"). Open https://www.youtube.com/embed/W7qWa52k-nE in your browser, you will only see the video player. That's why iframe work and show only the player.

Now, when you use jwplayer, you have only few lines to write, but you must import the library js and css files into the page. Lines you write will call functions in library.

To write a player with HTML5, you need to use and write some javascript events and functions (see: https://www.w3schools.com/tags/ref_av_dom.asp).

/* LIB */

function MyPlayer(playerContainer) {

    let videoElement;
    let videoPoster;

    const instance = {};

    instance.stop = () => {
        return new Promise(resolve => {
            videoElement.pause();
            videoElement.src = null;


            setTimeout(() => {
                resolve();
            });
        });
    };

    instance.setUrl = async(url) => {
        await instance.stop();
        videoElement.src = url;
        videoElement.load();
    };

    instance.play = () => {
        videoElement.play();
    };

    instance.playUrl = async(url) => {
        await instance.setUrl(url);
        instance.play();
    };
    
    instance.pause = () => {
        videoElement.pause();
    };
    
    instance.setPoster = (url) => {
      if(url) {
        videoPoster.style.backgroundImage = 'url(' + url + ')';
      } else {
        videoPoster.style.backgroundImage = null;
      }
    };

    const onPlayerEvent = (eventName, event) => {
      playerContainer.setAttribute('data-state', eventName);
    };
    const onCoverClick = (event) => {
      event.preventDefault();
      event.stopPropagation();
      
      if(videoElement.paused) {
        instance.play();
      } else {
        instance.pause();
      }
    };


    /* Player init */
    playerContainer.className += ' MyPlayer';
    playerContainer.setAttribute('data-state', 'emptied');
    playerContainer.innerHTML = '<video class="videoElement" poster="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"></video><div class="videoPoster"></div><div class="videoIndicator"></div><div class="playerLogo">MyPlayer</div><div class="videoCover"></div>';
    
    videoElement = playerContainer.getElementsByClassName('videoElement')[0];
    videoElement.addEventListener('emptied', onPlayerEvent.bind(this, 'emptied'), false);
    videoElement.addEventListener('loadstart', onPlayerEvent.bind(this, 'loadstart'), false);
    videoElement.addEventListener('canplay', onPlayerEvent.bind(this, 'canplay'), false);
    videoElement.addEventListener('playing', onPlayerEvent.bind(this, 'playing'), false);
    videoElement.addEventListener('pause', onPlayerEvent.bind(this, 'pause'), false);
    videoElement.addEventListener('waiting', onPlayerEvent.bind(this, 'waiting'), false);
    videoElement.addEventListener('ended', onPlayerEvent.bind(this, 'ended'), false);
    videoElement.addEventListener('error', onPlayerEvent.bind(this, 'error'), false);
    
    videoPoster = playerContainer.getElementsByClassName('videoPoster')[0];
    
    const videoCover = playerContainer.getElementsByClassName('videoCover')[0];
    videoCover.addEventListener('click', onCoverClick, false);
    videoCover.addEventListener('touch', onCoverClick, false);

    return instance;
}



/* USAGE */

const playerInstance = MyPlayer(document.getElementById('myPlayer'));
playerInstance.setPoster('https://www.w3schools.com/html/pic_trulli.jpg');
playerInstance.playUrl('https://www.w3schools.com/html/mov_bbb.mp4');

const playerInstance2 = MyPlayer(document.getElementById('myPlayer2'));
playerInstance2.setPoster('https://www.w3schools.com/html/pic_trulli.jpg');
playerInstance2.setUrl('https://www.w3schools.com/html/mov_bbb.mp4');
@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }

.MyPlayer {
  position: relative;
}

.MyPlayer .videoElement {
  background-color: black;
  width: 100%;
  height: 100%;
  vertical-align: bottom;
}

.MyPlayer .videoPoster, .MyPlayer .videoCover {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

.MyPlayer .videoPoster {
  opacity: 0;
  background-size: cover;
  transition: opacity .2s;
}
.MyPlayer[data-state="emptied"] .videoPoster, .MyPlayer[data-state="loadstart"] .videoPoster, .MyPlayer[data-state="canplay"] .videoPoster, .MyPlayer[data-state="ended"] .videoPoster {
  opacity: 1;
}

.MyPlayer .videoIndicator::before {
  position: absolute;
  top: 10px;
  left: 10px;
  color: #fff;
  text-shadow: 0 0 5px #000;
}
.MyPlayer[data-state="emptied"] .videoIndicator::before {
  content: '';
}
.MyPlayer[data-state="loadstart"] .videoIndicator::before, .MyPlayer[data-state="waiting"] .videoIndicator::before {
  content: '\25CC';
  font-size: 1.6em;
  animation:spin 4s linear infinite;
}
.MyPlayer[data-state="canplay"] .videoIndicator::before {
  content: '\25B6';
  font-size: 3em;
  right: 10px;
  text-align: center;
}
.MyPlayer[data-state="playing"] .videoIndicator::before {
  content: '\25B6';
  font-size: 1.3em;
}
.MyPlayer[data-state="pause"] .videoIndicator::before {
  content: '\2590\A0\258C';
}
.MyPlayer[data-state="ended"] .videoIndicator::before {
  content: '\27F2';
  font-size: 1.3em;
}
.MyPlayer[data-state="error"] .videoIndicator::before {
  content: '\2716';
}

.MyPlayer .playerLogo {
  position: absolute;
  right: 10px;
  bottom: 10px;
  font-size: 1.4em;
  color: #fff;
  text-shadow: 0 0 5px #f00;
  transition: color .2s, text-shadow .2s;
}
.MyPlayer[data-state="playing"]:not(:hover) .playerLogo {
  color: rgba(255, 255, 255, 0.4);
  text-shadow: 0 0 5px rgba(255, 0, 0, 0.4);
}
<div id="myPlayer" style="display:inline-block;max-width:250px;"></div> <div id="myPlayer2" style="display:inline-block;max-width:225px;"></div><br />
Video files from https//www.w3schools.com<br />
Video from https://www.bigbuckbunny.org/