Skip to content

Commit c454974

Browse files
Added autoplay next related video feature
1 parent e3694e9 commit c454974

File tree

4 files changed

+143
-4
lines changed

4 files changed

+143
-4
lines changed

css/styles.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ a {
100100
@media all and (min-width: 480px) {
101101

102102
#container {
103-
max-width: 450px;
103+
max-width: 470px;
104104
}
105105

106106
}

index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ <h3>
8888
<button class="btn" id="toggleDescription">
8989
Show Description
9090
</button>
91+
<button class="btn" id="toggleAutoplay">
92+
Autoplay
93+
</button>
9194
<button class="btn" id="toggleRepeat">
9295
Repeat Track
9396
</button>

js/everything.js

Lines changed: 139 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/* global gtag, URI, getSearchResults, getAutocompleteSuggestions, parseYoutubeVideoID, getYouTubeVideoDescription */
22

33
var keyCodes = {
4-
SPACEBAR: 32
4+
SPACEBAR: 32,
5+
ENTER: 13
56
};
67

78
var timeIntervals = {
@@ -15,6 +16,12 @@ var plyrPlayer;
1516
var youTubeDataApiKey = "AIzaSyCxVxsC5k46b8I-CLXlF3cZHjpiqP_myVk";
1617
var currentVideoID;
1718

19+
// global playlist, this is populated with an ajax call
20+
var tags = [];
21+
var playList = new Set();
22+
var autoplayState = false;
23+
const MAX_TAGS = 10;
24+
1825
var errorMessage = {
1926
init: function() {
2027
// nothing for now
@@ -137,6 +144,7 @@ var ZenPlayer = {
137144
that.setupTitle();
138145
that.setupVideoDescription(videoID);
139146
that.setupPlyrToggle();
147+
that.setupAutoplayToggle();
140148
});
141149

142150
plyrPlayer.addEventListener("playing", function() {
@@ -165,6 +173,17 @@ var ZenPlayer = {
165173
updateTweetMessage();
166174
});
167175

176+
// when player has finished playing
177+
plyrPlayer.addEventListener("ended", function() {
178+
if (autoplayState) {
179+
if (playList.length === 0 || playList.size === 0) {
180+
fetchSuggestedVideoIds();
181+
}
182+
var newId = getNewVideoID();
183+
that.playNext(newId);
184+
}
185+
});
186+
168187
plyrPlayer.addEventListener("timeupdate", function() {
169188
// Nothing is playing
170189
if (!plyrPlayer.plyr || !plyrPlayer.plyr.embed) {
@@ -223,6 +242,11 @@ var ZenPlayer = {
223242
});
224243
}
225244
},
245+
// play next song from autoplay
246+
playNext: function(videoID) {
247+
$("#v").val(videoID);
248+
$("#form").submit();
249+
},
226250
show: function() {
227251
$("#audioplayer").show();
228252
// Hide the demo link as some video is playing
@@ -258,6 +282,24 @@ var ZenPlayer = {
258282
toggleElement(event, ".plyr__video-wrapper", "Player");
259283
});
260284
},
285+
setupAutoplayToggle: function() {
286+
// toggle auto next song playing
287+
$("#toggleAutoplay").click(function(event) {
288+
var toggleTextElement = $("#" + event.currentTarget.id);
289+
if (autoplayState) {
290+
toggleTextElement.text("Start autoplay");
291+
autoplayState = false;
292+
window.sessionStorage.removeItem("autoPlay");
293+
window.sessionStorage.removeItem("playList");
294+
}
295+
else {
296+
toggleTextElement.text("Stop autoplay");
297+
autoplayState = true;
298+
window.sessionStorage.setItem("autoPlay", true);
299+
}
300+
});
301+
},
302+
261303
getVideoDescription: function(videoID) {
262304
var description = "";
263305

@@ -275,6 +317,7 @@ var ZenPlayer = {
275317
}
276318
else {
277319
description = data.items[0].snippet.description;
320+
tags = data.items[0].snippet.tags;
278321
}
279322
},
280323
function(jqXHR, textStatus, errorThrown) {
@@ -524,6 +567,81 @@ function pickDemo() {
524567
return demos[Math.floor(Math.random() * demos.length)];
525568
}
526569

570+
function updateAutoplayToggle(state) {
571+
if (state) {
572+
$("#toggleAutoplay").text("Stop autoplay");
573+
}
574+
else {
575+
$("#toggleAutoplay").text("Start autoplay");
576+
}
577+
}
578+
579+
function getNewVideoID() {
580+
var nextID = null;
581+
nextID = playList.pop();
582+
while (currentVideoID === nextID) {
583+
nextID = playList.pop();
584+
}
585+
window.sessionStorage.setItem("playList", JSON.stringify(playList));
586+
return nextID;
587+
}
588+
589+
function fetchSuggestedVideoIds() {
590+
if (playList.length === 0 || playList.size === 0) {
591+
if (tags.length) {
592+
// get similar videos, populate playList
593+
if (!isFileProtocol()) {
594+
for (let index = 0; index < tags.length && index < MAX_TAGS; index++) {
595+
$.ajax({
596+
url: "https://www.googleapis.com/youtube/v3/search",
597+
dataType: "json",
598+
async: false,
599+
data: {
600+
key: youTubeDataApiKey,
601+
part: "snippet",
602+
type: "video",
603+
order: "relevance",
604+
q: tags[index],
605+
maxResults: 2
606+
},
607+
success: onRelatedVideoFetchSuccess
608+
}).fail(function(jqXHR, textStatus, errorThrown) {
609+
logError(jqXHR, textStatus, errorThrown, "Related video lookup error");
610+
});
611+
}
612+
playList = Array.from(playList);
613+
window.sessionStorage.setItem("playList", JSON.stringify(playList));
614+
}
615+
}
616+
}
617+
}
618+
619+
function onRelatedVideoFetchSuccess(data) {
620+
// push items into playlist
621+
for (var i = 0; i < data.items.length; i++) {
622+
playList.add(data.items[i].id.videoId);
623+
}
624+
}
625+
626+
function loadAutoPlayDetails() {
627+
// load playList from session storage on reload
628+
if (window.sessionStorage.getItem("playList")) {
629+
playList = JSON.parse(window.sessionStorage.getItem("playList"));
630+
}
631+
632+
// fetch autoPlay from session storage on reload
633+
if (window.sessionStorage.getItem("autoPlay")) {
634+
autoplayState = window.sessionStorage.getItem("autoPlay");
635+
updateAutoplayToggle(autoplayState);
636+
}
637+
}
638+
639+
function resetAutoPlayList() {
640+
playList = new Set();
641+
tags = [];
642+
window.sessionStorage.removeItem("playList");
643+
}
644+
527645
$(function() {
528646
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
529647
$("#container").hide();
@@ -534,6 +652,8 @@ $(function() {
534652

535653
errorMessage.init();
536654

655+
loadAutoPlayDetails();
656+
537657
// How do we know if the value is truly invalid?
538658
// Preload the form from the URL
539659
var currentVideoID = getCurrentVideoID();
@@ -608,20 +728,22 @@ $(function() {
608728
data: {
609729
key: youTubeDataApiKey,
610730
part: "snippet",
611-
fields: "items/snippet/description",
612731
id: videoID
613732
},
614733
success: function(data) {
615734
if (data.items.length === 0) {
616735
window.location.href = makeSearchURL(formValue);
617736
}
618737
else {
738+
tags = data.items[0].snippet.tags;
619739
window.location.href = makeListenURL(videoID, formValueTime);
620740
}
621741
}
622742
}).fail(function(jqXHR, textStatus, errorThrown) {
623743
logError(jqXHR, textStatus, errorThrown, "Lookup error");
624744
});
745+
// fetching next videoIds for auto play
746+
fetchSuggestedVideoIds();
625747
}
626748
}
627749
else {
@@ -654,6 +776,8 @@ $(function() {
654776
// Handle demo link click
655777
$("#demo").click(function(event) {
656778
event.preventDefault();
779+
resetAutoPlayList();
780+
657781
gtag("send", "event", "demo", "clicked");
658782

659783
// Don't continue appending to the URL if it appears "good enough".
@@ -670,13 +794,22 @@ $(function() {
670794
// Handle focus link click
671795
$("#focus-btn").click(function(event) {
672796
event.preventDefault();
797+
resetAutoPlayList();
798+
673799
gtag("send", "event", "focus", "clicked");
674800
// Redirect to the favorite "focus" URL
675801
window.location.href = makeListenURL(focusId);
676802
});
677803

804+
// handle click on search icon
805+
$("#submit").click(function() {
806+
resetAutoPlayList();
807+
});
808+
678809
// Check if the current ID is the focus ID
679810
$(window).on("load", function() {
811+
loadAutoPlayDetails();
812+
680813
// Show Focus Button
681814
if (window.location.href.indexOf(focusId) === -1) {
682815
$("#focus-btn").show();
@@ -709,5 +842,9 @@ $(function() {
709842
if (evt.keyCode === keyCodes.SPACEBAR && !$("#v").is(":focus")) {
710843
evt.preventDefault();
711844
}
845+
846+
if (evt.keyCode === keyCodes.ENTER && $("#v").is(":focus")) {
847+
resetAutoPlayList();
848+
}
712849
});
713850
});

js/zap-common.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ function getYouTubeVideoDescription(videoID, youTubeDataApiKey, onSuccess, onFai
2727
data: {
2828
key: youTubeDataApiKey,
2929
part: "snippet",
30-
fields: "items/snippet/description",
3130
id: videoID
3231
},
3332
success: onSuccess

0 commit comments

Comments
 (0)