Custom Video Player using Polymer
Yes polymer, but before getting our hands dirty let’s have a short understanding of polymer. The polymer is a lightweight library which takes full advantage of new web standard called Web Components. With the help of Polymer, we can create web apps as well as custom HTML elements.
In our daily life, we use HTML elements like <video>, <input> and may more. The behavior of these elements defined by respective browsers and have few limitations. With the help of Polymer and web components, developers can define and decide the behavior of HTML elements.
What we will be building ?
Today we will create custom video element with the clean layout. When we use native web element video ,
i.e. <video src=”videoName.mp4″ controls></video>
It gives us the result as shown in below image.
But now how do we customize above video element, let’s say we want to display the title of the video or We want to change the color of this element.
We can do that by using Web components and Polymer
i.e. <my-video-player class=”green” src=”videoName.mp4″></my-video-player> and we can make something like:
Setting Up development environment.
In my opinion, the most decent way to start a new polymer project is by using seed-element project prepared by the Polymer team. When using seed-element project, we don’t need any provision to maintain structure or documentation page. The seed-element project provides a proper structure and some useful built-in features, along with a documentation page.
To start a new Polymer Project do the below steps:
- First download the source code of the seed-element project from here, and unzip it.
- Now rename the folder from seed-element project to your element’s name: my-video-player.
- Now to install all the dependencies using Bower (assuming you have installed Node, npm, gitand Bower on your machine).
- Run the below command to install the dependencies,
bower install
Great till now we have a well-documented project, now it’s time to run the seed-element project.
Starting our Server
Here we will use polyserve, a web server for developing elements. The most counseled tools related to developing Polymer elements is Polymer CLI . Check the list of tools available if you don’t want to use polyserve.
To install polyserve globally, Run the below command,
npm install -g polyserve
After installation, to execute the project run the below command and you should see below instruction in CMD:
polyserve
Create a Custom Video Player
In this section, we will understand the structure of Polymer element and we will replace seed-elementby our own my-video-player.
Polymer Element Structure
Before we propel our self ahead, let’s see the polymer element structure.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <dom–module> <!— template starts—> <template> <style> /* Styles for element */ </style> <!— Mark comes over here —> </template> <!— template ends —> <script> /* Logic behind element */ </script> </dom–module> |
In the above code.
- <template> : To create markup that will be rendered inside <my-video-player>.
- <style> : To style this element.
- <script> : Here we can declare methods ,properties and write other required logic.
Creating our elements ( adding Video and Title)
Now that we have understood how custom elements works let’s create our custom video element. In order to do that do the below steps,
1. Rename seed-element.html to my-video-player.html, which should be located inside root folder of your project.
- Open In the bower.jsonfile, rename the project to my-video-player.html.
- Open my-video-player.html and replace the existing <dom-module> code with below code.
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 | <dom–module id=“my-video-player”> <template> <style type=”text/css”> :host { width: 100%; height: 100%; } </style> <!— Video Title section starts—> <h1> {{ title }} </h1> <!— Video Title section ends—> <!—Adding Video —> <video id=“video” class=“video-section”> <source src=“{{ src }}” type=“{{ type }}” /> <video> </template> <script> Polymer({ ‘is’: ‘my-video-player’, ‘properties’: { ‘title’: String, ‘src’: String, ‘type’: String } }); </script> </dom–module> |
In the above code, you have noticed the id of dom-module is same the is property of Polymer object. By doing this, we declare a custom Polymer-based element with this name.
- Now in /demo folder, open index.html, edit the <link> element to import my-video-player.html as shown below,
1 | <link rel=“import” href=“../my-video-player.html”> |
- Once this is done, add the below markup inside body tag of the index.html.
1 | <my–video–player title=“my video player” src=“/src/test.mp4” type=“video/mp4” ></my–video–player> |
- Finally, Open your Demo page in your browser: http://localhost:8080/my-video-player/demo/ and you should see video element with a big title .
Creating a Layout
In our custom element, we have three section,
- First section : This holds the Button to play/pause, Title of the Video and lastly Timer.
- Second section :The seek bar resides inside this section.
- Third section : This section contains the video.
- Replace the markup of my-video-player.htmlwith below markup.
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 | <div id=“wrapper” class=“wrapper”> <!— First section starts —> <div class=“control-wrapper”> <!— Button to play/pause the video start—> <div class=“left-section” > </div> <!— Button to play/pause the video ends—> <!— Video Title section starts—> <div class=“middle-section”> <!— Video Title—> </div> <!— Video Title section starts—> <!— duration section starts—> <div class=“right-section”> <div id=“duration” class=“adjust”> <!— 00:00:00—> </div> </div> <!— duration section ends —> </div> <!— First section ends —> <!— Second section starts —> <div class=“seek-wrapper”> </div> <!— Second section ends —> <!— Third section starts —> <video id=“video” class=“video-section”> <source src=“{{ src }}” type=“{{ type }}” /> </video> <!— Third section ends —> </div> |
- Add the below styles inside <style> tag,
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 | :host { width: 100%; height: 100%; } .wrapper{ padding: 0px; position: relative; } .adjust { position: static; margin: auto; top: 0; right: 0; bottom: 0; left: 0; text–align: center; } .wrapper:hover > .control–wrapper{ opacity: 0.8; transition: opacity 2.5s; –webkit–transition: opacity 2.5s; } .wrapper:hover > .seek–wrapper{ opacity: 1; transition: opacity 2.5s; –webkit–transition: opacity 2.5s; } .control–wrapper{ –webkit–flex–direction: row; position: absolute; top: 0%; width: 100%; display: inline–flex; z–index: 5; box–shadow: 0 3px 0px rgba(0,0,0,.1); height: 40px; background: #fff; opacity: 0; transition: opacity 2.5s; –webkit–transition: opacity 2.5s; } .left–section, .right–section { height: 100%; position: relative; } .left–section { width: 40px; color: #fff; background–color: var(—paper–audio–player–color, #fff); } .middle–section { –ms–flex: 1; –webkit–flex: 1; flex: 1; width: 40px; text–align: center; line–height: 3; color: var(—paper–audio–player–color, #fff); } .right–section { width: 60px; line–height: 3; color: var(—paper–audio–player–color, #fff); } .seek–wrapper { –webkit–flex–direction: row; position: absolute; bottom: 0%; width: 100%; display: inline–flex; z–index: 5; box–shadow: 0 1px 0px rgba(0,0,0,.3); cursor: pointer; opacity: 0; transition: opacity 0.5s; –webkit–transition: opacity 0.5s; } .video–section{ width: 100%; height: 100%; padding: 0px; } |
Now, If you open demo page you will see a proper aligned video with the title. Make sure you have provided proper height/width to <my-video-player element.
Adding Controls
Till now we have clean UI now let’s add play/pause button and here we will use Iron-Icons andpaper-icon-button. So first, let’s save Iron-Icons as dependencies to our player,
bower install –save PolymerElements/iron-icon
bower install –save PolymerElements/paper-icon-button
Now when it’s done import below libraries in my-video-player.html.
1 2 3 | <link rel=“import” href=“../iron-icons/av-icons.html”> <link rel=“import” href=“../paper-icon-button/paper-icon-button.html”> |
Now add the below markup and styling in my-video-player.html.
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 | <div class=“left-section”> <paper–icon–button class=“adjust” id=“play” icon=“av:play-arrow” hidden$=“{{ isPlaying }}”> </paper–icon–button> <paper–icon–button class=“adjust” id=“pause” icon=“av:pause” hidden$=“{{ !isPlaying }}”> </paper–icon–button> </div> |
Let’s make it work,
Now we have play/pause button but if you click on those buttons nothing happens, to make that work we have to Bind On Click event on those buttons. The polymer provides some built-in listeners read more about Polymer events and Polymer gesture events.
Add on-click attribute in .left-section div on-clicks shown below.
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 | Polymer({ ‘is’: ‘my-video-player’, ‘properties’: { ‘title’: String, ‘src’: String, ‘type’: String, ‘isPlaying’: { ‘type’: Boolean, ‘value’: false } } ‘_playPause’: function(event) { event.preventDefault(); if (this.$.video.paused ) { this.$.video.play(); this.isPlaying = true; } else { this.$.video.pause(); this.isPlaying = false; } } }); |
In the above code _playPause() method,
- this.$.video refers to an internal node with the id=”video”.
- We are switching the value of this.isPlaying to true or false in order to show the play or pause button.
Adding Progress bar
To indicate the progress of video,here we will use custom Paper-Progress element. let’s first installPaper-Progress element using bower. run the below command,
1 | bower install —save PolymerElements/paper–progress |
Once it’s done, import the paper-progress.html into our my-video-player.html as shown below,
1 | <link rel=“import” href=“../paper-progress/paper-progress.html”> |
Now write below markup into the second section i.e. .seek-wrapper div,
1 2 3 4 5 | <div class=“seek-wrapper”> <paper–progress id=“progress”></paper–progress> </div> |
Till now paper-progress has its default styling let’s modify it so that it should look according to our layout. Add the below CSS into it,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | paper–progress { position: relative; width: 100%; —paper–progress–active–color: #27ae60; —paper–progress–height: 5px; —paper–progress–container–color: #fff; —paper–progress–transition–duration: 0.08s; —paper–progress–transition–timing–function: ease; —paper–progress–transition–transition–delay: 0s; } |
Let’s write some javascript in order to put life into our progress bar, here we will add two event listener to the video.
- The first method will be called when video element’s metadata gets loaded.
- The second method will update the progress bar.
In the below code,
- In the method, _setDuration() we are setting the max value of the paper-progress.
- _updateProgressBar() method will update the progress bar value.
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 | /* Registering event listeners */ ‘listeners’: { ‘video.loadedmetadata’: ‘_setDuration’, ‘video.playing’: ‘_updateProgressBar’, }, ‘_setDuration’: function() { this.$.progress.max = this.$.video.duration * 1000; }, ‘_updateProgressBar’: function() { var videoPlayer = this; videoPlayer.playerStatus = {}; if (videoPlayer.playerStatus.updateProgressInterval) { clearInterval(videoPlayer.playerStatus.updateProgressInterval); } videoPlayer.playerStatus.updateProgressInterval = setInterval( function(){ if ( videoPlayer.$.video.paused ) { clearInterval(videoPlayer.playerStatus.updateProgressInterval); } else { videoPlayer.$.progress.value = videoPlayer.$.video.currentTime * 1000; videoPlayer.currentTime = videoPlayer.$.video.currentTime; } }, 120); } |
Adding Timer
Let’s add the duration property into Polymer element, which we are showing the timer on right-top corner of the element.
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 | ‘properties’: { ‘title’: String, ‘src’: String, ‘type’: String, ‘isPlaying’: { ‘type’: Boolean, ‘value’: false }, ‘duration’: { ‘type’: Number, ‘value’: 0 } } |
Now let’s add the below markup inside our template,
<div class="crayon-info" style="min-height: 19 ereccion sin viagra.6px !important; line-height: 19.6px !important;”>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <div class=“right-section”> <div id=“duration” class=“adjust”> {{ duration }} </div> </div> We already added styles for the duration, now let‘s work on javascript to display duration of the video when the video’s metadata gets loaded. ‘_setDuration’: function() { this.$.progress.max = this.$.video.duration * 1000; this.duration = this.$.video.duration; } |
Okay now open the demo page, You should see the time at right top corner. But we want to update the duration when video is still playing, to achieve this we will modify _updateProgressBar() method as shown below,
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 | ‘_updateProgressBar’: function() { var videoPlayer = this; videoPlayer.playerStatus = {}; if (videoPlayer.playerStatus.updateProgressInterval) { clearInterval(videoPlayer.playerStatus.updateProgressInterval); } videoPlayer.playerStatus.updateProgressInterval = setInterval( function(){ if ( videoPlayer.$.video.paused ) { clearInterval(videoPlayer.playerStatus.updateProgressInterval); } else { videoPlayer.$.progress.value = videoPlayer.$.video.currentTime * 1000; videoPlayer.currentTime = videoPlayer.$.video.currentTime; videoPlayer.duration = videoPlayer.$.video.currentTime; } }, 120); } |
One last thing, You have noticed that time is Striking link long number, so let’s convert it into more human readable form, add the below method into polymer:
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 | ‘_getProperTime’: function(totalSeconds){ var time = “”; var hours = Math.floor(totalSeconds / 3600); totalSeconds %= 3600; var minutes = Math.floor(totalSeconds / 60); var seconds = Math.floor(totalSeconds % 60); if (hours > 0) { if (hours < 10 ) { hours = “0” + hours; } time += hours+“:”; } if (minutes < 10 ) { minutes = “0” + minutes; } if (seconds < 10) { seconds = “0” + seconds; } time += minutes +“:”+ seconds; return time; } Now let‘s call this method from our markup by modifying the below code, <div class=“right-section”> <div id=“duration” class=“adjust”> {{ _getProperTime(duration) }} </div> </div> |
Once again open your demo page, you should see awesome custom video element with clean styled Play/Pause button, Title, Timer and progress bar.
Note: Code for seek bar available in source code download.
Conclusion
In this article, we learned many things from web component to creating our custom element. We saw how we Polymer element structure works, how to set up a development environment and how to use other polymer elements into our custom element.
However, web components and polymer both are new standards but most of the browsers now have support for it, so what are you waiting for start developing your own elements and share your thoughts in below comment box.
Tutorial Categories:
Tutorial Categories:
Pls tell the admin that download function is not working.