Creating YouTube video timestamps on WordPress - MB Views
You might know the timestamps feature on YouTube, but how can you have it for videos on your site? Rather than waiting for a complete video to run from zero seconds to the point you are referring to, timestamps enable you to jump to any second of the video directly where a timestamp regulates. You can add timestamps as many as the parts you want to have fast access. Let’s create YouTube video timestamps using MB Views!
This is an example I’d like to create today:
Video Version
Preparation
In this practice, I assume that each video is saved in a post of a custom post type. To make the timestamps easier, we should save the video URL in a custom field instead of in the content of the post. Then, we will use custom fields created with Meta Box to input timestamps and short descriptions for them.
In this practice, we need these tools:
- Meta Box core plugin: to have a framework to create custom fields, and also the custom post type if any;
- MB Views: to create and style the template for the page without touching the theme files;
- Meta Box Builder: to have a UI on the back end to create custom fields.
You can install them individually or use Meta Box AIO.
1. Creating custom fields
As mentioned, I’ll create a field to input the ID of the video. It is a part of the video URL, and we just need this for quick and short saving. You can find this ID on the URL of the video as you can see here.
The Timestamp and Description will be grouped in pairs and were set to add more than one timestamp for each video, as follows.
Now, move to the Meta Box > Custom Fields to create them.
Choose the Text field for the video ID.
Insert a Group field for timestamps.
We should set it to be collapsible since there may be too many timestamps you want to add. Also, turn on the Cloneable option to set the group to be cloneable. This helps to add multiple pairs of timestamps and its descriptions.
After configuring all the fields, move to the Settings tab. Choose Location as Post type and select a post type to which you want to assign these fields
Then, go to the post editor, and you will see the fields displayed.
2. Displaying the timestamps
2.1. Getting timestamps from custom fields
As I said, I will not add video directly to the post as usual. I will use the MB Views to display it, as well as along with the timestamps.
Go to MB Views to create a template for it.
As usual, to get data from custom fields, we just go to insert the wanted field from this list.
The timestamps are in a cloneable group, so whenever you click to the group, a loop will be generated in the template.
Then, insert the subfield inside.
Insert the Video ID field as the same.
Now, move to the settings of the view, since we will display the timestamps in each post, choose the type as Singular.
And choose the post type you want.
Now, go to a post on frontend, and you will see the result. Still there is no video displayed, and all of the timestamps just are text now.
So, we should go back to the template and customize the code a bit more to display the video and make the timestamps work as we expected.
2.2. Converting data for using JavaScript
We should use JavaScript to display the video from the video ID, as well as display timestamps in the clickable style and make them work on the video. That’s why we are going to have an array to store the values and transfer them to a HTML tag for using JavaScript later.
Back to the template created with MB Views. First, create an array to store the timestamps and descriptions. Add this code at the first line.
{% set TimestampsArray = [] %}
Then, add these lines of code to pass the value from custom fields to the array.
{% set TimestampsArray = TimestampsArray|merge(
[
{
"timestamp": ,
"description":
}
] ) %}
{{clone.timestamp}}
and {{clone.description}}
are the ones to get data from custom fields. So, move them to the 6th and 7th lines as follows.
Also remove the {{ }}
symbols.
I also have another array to store the video ID along with the timestamps and description.
{%
set TimestampsObject =
[
{"id": },
{
'Timestamps':
}
]
%}
Also move {{ post.video_id }}
to assign it to the array.
Fill in the name of the first array to the Timestamps
key, then the timestamps and description from it will be get and pass to the new array as well.
Add the code <div id="video_player"></div>
. This is an HTML ID that’ll be used to display video using JavaScript later.
There’s nothing displayed in the template so far.
To display the timestamps, insert fields from the list on the right sidebar once again.
Add an A tag to the line where we display the timestamps information:
<li><a href="javascript:void(0);" onclick="setCurrentTime({{loop.index0}})"> </a></li>
onclick="setCurrentTime({{loop.index0}})"
is an attribute that helps to trigger the moment someone clicks on the timestamp and its description. It’ll let us know where they want to jump to on the timeline of the player.
As well as, based on that event, we will force the player to play from the regulated time.
Next, for JavaScript, add this line:
<div id="Timestamps_ID" data-timestamp='{{TimestampsObject|json_encode()}}'></div>
It’s to create an HTML tag with the data-timestamp attribute to obtain data from the created array.
2.3. Adding JavaScript
As mentioned, we use JavaScript to display the video, and make the timestamps work on the video as well.
Still in the template created with MB Views, move to the JavaScript tab.
Add some codes as follows to convert the JSON that we created in the template to an array containing JavaScript objects named TimestampsObjectData
.
var getTimestampsID = document.getElementById("Timestamps_ID");
var TimestampsObjectData = JSON.parse(getTimestampsID.getAttribute("data-timestamp"));
We must do this to make the following scripts run.
The next part is to initialize a YouTube player based on YouTube API.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
my_player = new YT.Player('video_player', {
videoId: TimestampsObjectData[0].id,
host: 'http://www.youtube.com',
});
}
video_player
is the HTML ID that I created in the template.
videoId: TimestampsObjectData[0].id,
helps to get the ID of the video from the TimestampsObjectData array
.
[0].id stipulates
that only the ID will be get.
Also in this script, I created my_player
JavaScript object converted from the player. This object will help to create a JavasScript action to jump to a specific position on the timeline.
Next, we should convert time to seconds using the following lines of code. We usually use 0:00 - 0:30 - 1:13 format for video timing. Then, we should convert it to 0 - 30 - 73 format.
// Converting Time to Seconds
function hmsToSecondsOnly(str) {
var p = str.split(':'),
s = 0, m = 1;
while (p.length > 0) {
s += m * parseInt(p.pop(), 10);
m *= 60;
}
return s;
}
In the template, we had an attribute onclick="setCurrentTime({{loop.index0}})"
to trigger which timestamp the user clicked on. So now, we have some lines to admit that moment and force the player to play from the clicked timestamp.
function setCurrentTime(slideNum) {
Timeobject = TimestampsObjectData[1].Timestamps;
Timeobject = Timeobject.map(function (item) {
return hmsToSecondsOnly(item.timestamp)
})
my_player.seekTo(Timeobject[slideNum]);
}
setCurrentTime(slideNum)
is the mentioned attribute.
Timeobject = TimestampsObjectData[1].Timestamps;
is to get data about the timestamps from the TimestampsObjectData
object.
The values stored in this array will have the form as [0:00,Intro ; 0:30,Before Getting Started ; 1:13,Create a Custom Post Type]. It includes the timestamps and their descriptions. However, we need the timestamps only for this action. Then, we have the below lines to remove the description.
As well as the return values will be converted to seconds format. And now, the array will be [0,30,73] format.
From those values in the array, [slideNum]
is from the attribute onclick="setCurrentTime({{loop.index0}})
, and will check it matches to which value in the array. Then, it will find out exactly the position on the timeline of the player that the user wants to jump to.
my_player.seekTo(Timeobject[slideNum]);
will help to jump to that position.
Now, go to a post on frontend, you will see the video player frame, along with the timestamp. Whenever you click on a timestamp, the player will jump to the corresponding time on the timeline and play.
2.4. Styling the page
If you want to change the displaying of the timestamp, back to the template and custom the code one more time. I’m adding some headings, and classes.
<h2>Video Version</h2>
<div class="video-container">
<div id="video_player"></div>
<div class="video-timestamp">
<div id="Timestamps_ID" data-timestamp='{{TimestampsObject|json_encode()}}'></div>
<strong>Timestamps:</strong>
<ul>
{% for clone in post.timestamps %}
<li><a href="javascript:void(0);" onclick="setCurrentTime({{loop.index0}})"> {{ clone.timestamp }} {{ clone.description }}</a></li>
{% endfor %}
</ul>
</div>
</div>
And now, using CSS to change the style.
.video-container ul{
list-style: none;
padding-left: 0px;
}
.video-container ul li {
padding:5px 0px;
}
Now, go back to the page on the frontend, you’ll see a new look of the page.