If you’re looking to create a website for streaming movies, web series, and anime using Public APIs, you’ve come to the right place. In this tutorial, we’ll walk you through the steps of creating a website that allows users to watch their favorite content for free.
Approach: So our approach for creating this type of web app is very simple.
- First of all, well will use the IMDB API to search our favorite content and get its IMDB Id.
- Now we will pass the IMDB Id to 2Embed iframe API that will show us our content.
- We will use the TMDB API for web shows because IMDB does not provide the episode data of web shows.
- Further, the episode data is passed in the 2Embed iframe API that will play our favorite web show.
Prerequisites: You have to create a developer account at TMDB (The Movie Database) and had to get an API key.
Step 1: Setting up the HTML file: First, we will create an HTML file and add the necessary elements to it. In this case, we need a search bar, video player, share button, and a section for search results. Here’s an example of the HTML code:
Step 2: Setting up the Javascript file: Now we have to set up the Javascript to make our app functional. We will first set up some variables that we will further use in our code many times.
<!DOCTYPE html> < html lang = "en" >
< head >
< meta charset = "UTF-8" >
< link rel = "manifest" href = "/manifest.json" >
< link rel = "apple-touch-icon" href = "/icons/apple-touch-icon.png" >
< link rel = "shortcut icon" href = "icons/icon.ico" type = "image/x-icon" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< meta name = "theme-color" content = "#4285f4" />
< meta name = "robots" content = "index, follow" >
< meta property = "og:image" < meta name = "description"
content="Discover and stream your favorite movies
and TV shows with NETFLIX KE PITAJI -
an open source content search and watch website.
Enjoy unlimited access to a vast library of
content for free.">
< title >NETFLIX KE PITAJI</ title >
< link rel = "preload stylesheet" href = "style.min.css" as = "style" >
< link rel = "preload stylesheet" href = "center-atom.min.css" as = "style" >
< script async src = "jquery.js" ></ script >
<!-- Google tag (gtag.js) -->
< script defer src = "..." >
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'G-THTQ9GZQ0J');
</ script >
<!-- Serviceworker code for PWA -->
< script >
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('/sw.js')
.then(function (registration) {
console.log('Service worker registered: ',
registration.scope);
}).catch(function (error) {
console.log(
'Service worker registration failed: ', error);
});
});
}
</ script >
</ head >
< body >
< div class = "search-container" >
< input type = "search" id = "search-input" placeholder = "Search any Movie/Webseries/Anime" >
< button id = "search-button" >Search</ button >
</ div >
< center >
< div id = "video" class = "video" >
< iframe id = "iframe" src = "" frameborder = "0" webkitallowfullscreen
mozallowfullscreen
allowfullscreen>
</ iframe >
< p style = "color: rgb(79, 221, 221); font-weight: 500;" >
In case of any Error or Too Much Buffering click
again on your Movie poster down below or just
change the Server from the left corner in video player.
</ p >
<!-- Go to www.addthis.com/dashboard to customize your tools -->
< div class = "addthis_inline_share_toolbox" ></ div >
< div id = "webSeriesData" ></ div >
</ div >
</ center >
< div id = "results" ></ div >
< center style = "margin-top: 2vh;" >
< div class = "alwaysVisibleContent" >
< h1 >< u >NETFLIX KE PITAJI</ u ></ h1 >
< h2 style = "color: rgb(55, 255, 255);" >
Netflix, on us. Free
</ h2 >
< h3 >Search any Movie/Webseries/Anime</ h3 >
< div class = "pagelinks" >
< a href = "/privacy-policy.html" target = "_blank" >
Privacy Policy
</ a >
< a href = "/terms-and-conditions.html" target = "_blank" >
Terms And Conditions
</ a >
< a href = "" target = "_blank" >
Source Code
</ a >
< a href = "/contact.html" target = "_blank" >
Contact
</ a >
</ div >
</ div >
< div class = "information" >
< h2 >< u >PROJECT INFORMATION</ u ></ h2 >
< h3 >Introduction</ h3 >
< p >
Netflix ke Pitaji is a one-of-a-kind,
open-source project that allows users to
search and retrieve data about Movies and
Web Shows available on the Internet. This
documentation provides a comprehensive overview of
the features and functionality of the website, including
its data sources, user interface, and community features.
</ p >
< h3 >Data Sources</ h3 >
< p >
Netflix ke Pitaji retrieves data from two of the
largest movie and TV databases on the internet:
IMDB(Internet Movie Database) and TMDB (The Movie
Database). This combination of data sources
provides a comprehensive and up-to-date movie and
TV show library, ensuring that users have access to
the latest information on their favorite movies and
TV shows.
</ p >
< h3 >User Interface</ h3 >
< p >
The website has a simple and user-friendly interface,
making it easy for users to navigate and search for
movies and TV shows. The no reload feature of this
website makes it very unique and super fast. The page
load speed of this website is approximately 0.1 Seconds.
</ p >
< h3 >Movie and TV Show Information</ h3 >
< p >
The movie and TV show pages on Netflix ke Pitaji
provide users with a wealth of information about the
movie or TV show. The page includes the poster
thumbnail, and information about cast and crew.
More information about the Movies and Shows is
intentionally not displayed, If you want to display
that information then you can modify
that in the source code.
</ p >
< h3 >Single Page Website</ h3 >
< p >
It is important to note that Netflix ke Pitaji is a
single page client side website and does not store any
information on its servers. All data is retrieved
from IMDB and TMDB and is displayed on the website
in real-time. Despite of being a single page website
the Url's in addres bar are updated and their event
is also handled. Means if you enter a url which
contains some data about movies/webseries/search_query
the website will load that data same as a normal website
with backend does. This means that the website is fast
and responsive, providing a seamless user experience
for its users.
</ p >
< h3 >Source Code</ h3 >
< p >
The Source Code of this Tool is available at Github
repository by Pulkit Pareek. You can access the
repository
at < a style = "color:rgb(0, 140, 255);margin:0%" title = "Link to Github Repository"
href = "..." target = "_blank" >
Here(Link to Github Repository
</ a >.
</ p >
< h3 >Conclusion</ h3 >
< p >
In conclusion, Netflix ke Pitaji is an open-source
project that provides a comprehensive movie and TV
show library and a unique movie-watching experience.
With its simple and user-friendly interface,comprehensive
movie and TV show information, and the ability to
watch movies and TV shows that are available on the internet
for free.
</ p >
< h3 >Libraries Used</ h3 >
< div class = "footerLinks" >
< a href = "..." target = "_blank" >
2Embed
</ a >
target = "_blank" >
jQuery
</ a >
< a href = "..." target = "_blank" >
PACE
</ a >
< a href = "..." target = "_blank" >
TMDB
</ a >
< a href = "..." target = "_blank" >
IMDB
</ a >
< a href = "..." target = "_blank" >
CORS-Proxy
</ a >
</ div >
</ div >
</ center >
< script src =
</ script >
< script src = "script.min.js" ></ script >
< script async src = "..."
crossorigin = "anonymous" >
</ script >
</ body >
</ html >
|
.search-container { display : flex;
height : 10 vh;
position : fixed ;
justify- content : center ;
align- content : center ;
flex- direction : row;
flex-wrap: nowrap ;
align-items: center ;
z-index : 10 ;
} input { padding : 0.2 rem;
font-size : 1 rem;
border-radius: 5px ;
border : 0.1 vw solid gray ;
padding : 0.7 vw;
margin : 0.5 vw;
width : 19 rem;
outline : none ;
} input:focus { border : black solid 0.2 vw;
box-shadow: rgba( 2 , 255 , 242 , 0.596 ) 0 vw 0 vw 1.6 vw 0.2 vw;
} button { padding : 0.55 rem 0.4 rem;
background-color : blue ;
color : white ;
border-radius: 5px ;
border : none ;
cursor : pointer ;
text-align : center ;
font-size : 1 rem;
} button:hover { color : #000000 ;
font-weight : bold ;
background-color : rgb ( 0 , 247 , 255 );
box-shadow: rgba( 2 , 255 , 242 , 0.596 ) 0 vw 0 vw 1.6 vw 0.2 vw;
} #results { margin-top : 5 vh;
display : flex;
flex-wrap: wrap;
flex- direction : row;
align- content : center ;
justify- content : center ;
align-items: center ;
} .result { width : 14 vw;
height : fit-content;
margin : 2 vw;
border : 0.1 vw solid rgb ( 190 , 190 , 190 );
box-shadow: rgba( 211 , 211 , 211 , 0.322 ) 0px 0px 2 vw 0.05 vw;
border-radius: 5px ;
overflow : hidden ;
transition-duration: 0.5 s;
} .result:hover { width : 18 vw;
transition-duration: 0.5 s;
box-shadow: rgba( 211 , 211 , 211 , 0.322 ) 0px 0px 7 vw 1 vw;
} .hoverClass { width : 16.7 vw !important ;
transition-duration: 0.5 s;
box-shadow: rgba( 211 , 211 , 211 , 0.322 ) 0px 0px 7 vw 1 vw;
} .result img { width : 100% ;
object-fit: cover;
} .result .info { padding : 0.7 vw;
} .result .info h 3 {
margin : 0 ;
} .result .info h 3: hover {
color : #39cdbc ;
font-weight : bold ;
text-shadow : #39cdbc 0px 0 vw 5 vw;
} .hoverClass .info h 3 {
color : #39cdbc ;
font-weight : bold ;
text-shadow : #39cdbc 0px 0 vw 5 vw;
} .result .info p { margin : 0 ;
font-size : 1 vw;
color : gray ;
} .result .info p:hover { color : rgb ( 90 , 212 , 192 );
font-weight : 500 ;
text-shadow : #8fe6db 0px 0 vw 5 vw;
} .hoverClass .info p { color : rgb ( 90 , 212 , 192 );
font-weight : 500 ;
text-shadow : #8fe6db 0px 0 vw 5 vw;
} a { text-decoration : none ;
} .episodes { background-color : #d8d8d8 ;
padding : 1 vw;
margin : 0.5 vw;
font-size : large ;
color : #000 ;
text-decoration : none ;
border-radius: 1.1 vw;
} .episode-container { display : flex;
flex- direction : row;
flex-wrap: wrap;
justify- content : center ;
align- content : center ;
align-items: center ;
} .episodes:hover { background-color : #39cdbc ;
color : #ffffff ;
font-weight : bold ;
} .selected { background-color : #39cdbc ;
color : #ffffff ;
font-weight : bold ;
} body { font-family : system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI' , Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans' , 'Helvetica Neue' , sans-serif ;
background-color : #111111 ;
display : flex;
flex- direction : column;
flex-wrap: nowrap ;
align-items: center ;
} h 1 ,
h 2 ,
h 3 {
color : whitesmoke;
z-index : 10 ;
} iframe { width : 72 vw;
height : 36 vw;
box-shadow: rgba( 211 , 211 , 211 , 0.322 ) 0px 0px 7 vw 1 vw;
margin-top : 10 vh;
top : 10 ;
} #video { display : none ;
} .information { margin : 5 vw;
} .information h 3 {
font-size : 3 vw;
font-family : 'Segoe UI' , Tahoma , Geneva, Verdana , sans-serif ;
} .information p { color : #39cdbc ;
font-size : 2 vw;
font-weight : 700 ;
} h 2 {
font-size : 3 vw;
font-family : 'Segoe UI' , Tahoma , Geneva, Verdana , sans-serif ;
color : aqua ;
} h 3 {
font-size : 3 vw;
} .information a, li { margin : 1 vw;
color : blue ;
font-size : x-large ;
font-weight : 500 ;
} .information a:hover { color : rgb ( 0 , 225 , 255 ) !important ;
} .pagelinks a { margin : 1 vw;
font-size : x-large ;
font-weight : 500 ;
color : #00b7ff !important ;
font-weight : bolder ;
text-decoration : underline ;
} .pagelinks a:hover { color : #ae00ff !important ;
} .pagelinks { display : flex;
flex- direction : row;
justify- content : center ;
align-items: center ;
} .footerLinks a { color : #b803ff !important ;
} .info h 3 {
font-size : 1.6 vw;
} /* Responsive Configuration */ @media only screen and ( max-width : 768px ) {
iframe {
width : 100 vw !important ;
height : 50 vw !important ;
/* display: none; */
box-shadow: rgba( 211 , 211 , 211 , 0.322 ) 0px 0px 7 vw 1 vw;
margin-top : 7 vh;
top : 10 ;
}
.search-container {
height : 5 vh;
}
input {
width : 18 rem !important ;
padding : 0.4 rem 0.4 rem;
}
h 1 {
font-size : 7 vw;
}
h 2 {
font-size : 7 vw;
}
h 3 {
font-size : 5 vw;
}
.info h 3 {
font-size : 3 vw;
}
.result {
width : 25 vw;
margin : 2 vw;
}
.hoverClass {
width : 36 vw !important ;
transition-duration: 0.5 s;
box-shadow: rgba( 211 , 211 , 211 , 0.322 ) 0px 0px 7 vw 1 vw;
}
.result:hover {
width : 36 vw;
transition-duration: 0.5 s;
box-shadow: rgba( 211 , 211 , 211 , 0.322 ) 0px 0px 7 vw 1 vw;
}
.information p {
font-size : 4 vw;
}
.information a {
font-size : 4 vw;
}
.information h 3 {
font-size : 7 vw;
}
.result .info p {
font-size : 1.8 vw;
}
.pagelinks {
flex- direction : column;
}
.pagelinks a {
font-size : 5 vw;
}
} @media only screen and ( max-width : 414px ) {
.information p {
font-size : 6 vw;
}
.information h 3 {
font-size : 11 vw;
}
button {
padding : 0.48 rem 0.4 rem;
}
input {
width : 74 vw !important ;
}
.result {
width : 40 vw;
margin : 2 vw;
}
.result:hover {
width : 45 vw;
transition-duration: 0.5 s;
box-shadow: rgba( 211 , 211 , 211 , 0.322 ) 0px 0px 7 vw 1 vw;
}
.hoverClass {
width : 45 vw !important ;
transition-duration: 0.5 s;
box-shadow: rgba( 211 , 211 , 211 , 0.322 ) 0px 0px 7 vw 1 vw;
}
.information a {
font-size : 7 vw;
}
.info h 3 {
font-size : 4 vw;
}
.result .info p {
font-size : 3 vw;
}
.result .info {
padding : 0.9 vw;
}
.pagelinks a {
font-size : 7 vw;
}
} @media only screen and ( min-width : 1400px ) {
button {
padding : 0.7 vw 1 vw;
font-size : 1.5 vw;
}
input {
font-size : 1.5 vw;
width : 30 vw;
}
h 1 {
font-size : 4 vw;
}
h 2 {
font-size : 3 vw;
}
.info p {
font-size : 1 vw !important ;
}
h 3 {
font-size : 1.5 vw;
}
.hoverClass {
width : 16.4 vw !important ;
transition-duration: 0.5 s;
box-shadow: rgba( 211 , 211 , 211 , 0.322 ) 0px 0px 7 vw 1 vw;
}
.information a {
font-size : 2 vw;
}
.alwaysVisibleContent h 3 {
font-size : 2 vw;
}
.pagelinks a {
font-size : 2 vw;
}
} @media only screen and ( min-width : 1600px ) {
.result {
width : 13 vw;
margin : 1 vw;
}
} |
function scrollToTop() {
const c = document.documentElement.scrollTop ||
document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
} const searchInput = document.getElementById( "search-input" );
const searchButton = document.getElementById( "search-button" );
const resultsContainer = document.getElementById( "results" );
const corsProxy = "..." ;
// functions that manipulates the queries of url to get a //low resolution image to increase page speed function optimisedImageUrl(url) {
return url.replace( "._V1_." , "._V1_QL75_UX160_." );
} // Fetch and Show Cards function fetchAndShow() {
const query = encodeURIComponent(searchInput.value);
const url = `${
corsProxy}...${query}.json`;
Pace.restart();
fetch(url)
.then((response) => response.json())
.then((data) => {
const results = data.d;
resultsContainer.innerHTML = "" ;
results.forEach((result) => {
if (result.i && (result.qid === "movie" ||
result.qid === "tvSeries" )) {
const resultElem = document.createElement( "div" );
resultElem.classList.add( "result" );
resultElem.setAttribute( "IMDB" , result.id);
let imageAndInfo = "" ;
if (result.qid === "movie" && result.i) {
imageAndInfo = `<a onClick= "setUrl(this);
return setVideo(this);" url=
"imdb=${result.id}&type=movie&title=${
result.l.replace(/ /g, " _ ")}" isWebSeries= "
false" title= "${result.l}" class= "links" IMDB= "${result.id}" href= "..." target= "_blank" >
<img alt= "${result.l}" src= "${
optimisedImageUrl(result.i.imageUrl)}" >
<div class= "info" >
<h3>${result.l}</h3>
<p>${result.s}</p>
</div>
</a>`;
} else if (result.qid === "tvSeries" && result.i) {
imageAndInfo = `<a onClick= "setUrl(this);
return setVideo(this);" url= "imdb=${result.id}&season=1&episode=1&title=
${result.l.replace(/ /g, " _ ")}" IMDB= "${result.id}" title= "${result.l}" isWebSeries= "true" class= "links" href= "...=${result.id}&s=1&e=1" target= "_blank" >
<img alt= "${result.l}" src= "${optimisedImageUrl(result.i.imageUrl)}" >
<div class= "info" >
<h3>${result.l}</h3>
<p>${result.s}</p>
</div>
</a>`;
}
resultElem.innerHTML = imageAndInfo;
resultsContainer.appendChild(resultElem);
}
});
});
} // A function which will set the player url and page //url by imitating a anchor tag click function setAll(imdb, title, season, episode, type) {
if (imdb && title && !season && !episode && type) {
let a = document.createElement( "a" );
a.setAttribute( "onClick" , "setUrl(this); return setVideo(this);" );
a.setAttribute(
"url" ,
`imdb=${imdb}&type=movie&title=${title.replace(/ /g, "_" )}`
);
a.setAttribute( "isWebSeries" , "false" );
a.setAttribute( "title" , title);
a.setAttribute( "class" , "links" );
a.setAttribute( "IMDB" , imdb);
a.setAttribute( "href" , "...=" + imdb);
a.setAttribute( "target" , "_blank" );
a.click();
} else if (imdb && title && episode && !type) {
// let formatedEpisodeNumber =
(episode).toLocaleString( 'en-US' ,
{ minimumIntegerDigits: 2, useGrouping: false });
let a = document.createElement( "a" );
a.setAttribute( "onClick" , "setUrl(this);
return setVideo(this);" );
console.log( "season setall" , season, "episode" , episode);
a.setAttribute( "url" , `imdb=${imdb}&season=$
{season}&episode=${episode}`);
a.setAttribute( "isWebSeries" , "true" );
a.setAttribute( "title" , title);
a.setAttribute( "class" , "links" );
a.setAttribute( "IMDB" , imdb);
a.setAttribute(
"href" ,`...=${season}&e=${episode}`
);
a.setAttribute( "target" , "_blank" );
a.click();
}
} // fetch titile of movie/webseries by its imdb id const fetchTitle = async (imdbID) => { const url = `${corsProxy}....json`;
try {
const response = await fetch(url);
const data = await response.json();
const title = data.d[0].l;
return title;
} catch (error) {
console.error(error);
}
}; // set url of element by getting its custom url attirbute function setUrl(element) {
let search = element.getAttribute( "url" );
window.history.replaceState({}, "" , `?
${search.replace(/%20/g, "+" )}`);
} // insert search query in search box from url and //set contents from url function fillSearchInput() {
let searchParams = new URLSearchParams(window.location.search);
let search = searchParams.get( "search" );
let season = searchParams.get( "season" );
let episode = searchParams.get( "episode" );
let imdb = searchParams.get( "imdb" );
let type = searchParams.get( "type" );
// It will set search query in search box from url
if (search && !season && !episode && !imdb) {
search = search.replace(/\+/g, "%20" );
const searchInput = document.querySelector( "#search-input" );
searchInput.value = search;
fetchAndShow();
}
// It will set the contents according to url data
else if (imdb && type && !search && !episode && !season) {
fetchTitle(imdb)
.then((title) => setAll(imdb, title, season, episode, type))
. catch ((error) => console.error(error));
// It will set the contents according to url data
} else if (imdb && !search && episode && season) {
console.log( "season" , season, "episode" , episode);
fetchTitle(imdb)
.then((title) => setAll(imdb, title, season, episode, type))
. catch ((error) => console.error(error));
console.log( "season" , season, "episode" , episode);
}
} fillSearchInput(); // update url by search query function updateURL(input) {
let search = input.value;
if (search) {
window.history.replaceState(
{},
"" ,
`?search=${encodeURIComponent(search).replace(/%20/g, "+" )}`
);
} else {
window.history.replaceState({}, "" , window.location.pathname);
}
} // Highlighting Selected Card function highlightCards() {
let searchParams = new URLSearchParams(window.location.search);
let imdb_id = searchParams.get( "imdb" );
try {
document.querySelectorAll( ".result" ).forEach( function (card) {
card.className = "result" ;
});
document.querySelector(`div[IMDB=${imdb_id}]`).className =
"result hoverClass" ;
} catch (error) {
// will throw error only if the class is not present
}
} // Listen for the onpopstate event and update the //display of elements with the class "information" window.onpopstate = function () {
let searchParams = new URLSearchParams(window.location.search);
let search = searchParams.get( "search" );
let imdb = searchParams.get( "imdb" );
if (search || imdb) {
let elements = document.getElementsByClassName( "information" );
for (let i = 0; i < elements.length; i++) {
elements[i].style.display = "none" ;
}
} else {
let elements = document.getElementsByClassName( "information" );
for (let i = 0; i < elements.length; i++) {
elements[i].style.display = "block" ;
}
}
}; // ajax auto search by input which will execute //when user stops typing for 500ms let timer; searchInput.addEventListener( "keyup" , function () {
let inputQuery = this ;
clearTimeout(timer);
timer = setTimeout( function () {
updateURL(inputQuery);
fetchAndShow();
window.dispatchEvent( new PopStateEvent( "popstate" ));
$( "html,body" ).animate(
{
scrollTop: $( "#results" ).offset().top,
},
"slow"
);
}, 500); // wait for 500ms before executing the function
}); // button click search searchButton.addEventListener( "click" , function () {
fetchAndShow();
// hide information
window.dispatchEvent( new PopStateEvent( "popstate" ));
}); // higlight episodes of webseries function episodeHighlight(cssidentification = "s1e1" ) {
document.querySelectorAll( ".episodes" ).forEach( function (episode) {
episode.className = "episodes" ;
});
document.querySelector(
`.episodes[cssidentification= '${cssidentification}' ]`
).className = "episodes selected" ;
} // Do multiple tasks on anchor tag click function setVideo(element) {
const iframe = document.getElementById( "iframe" );
const video = document.getElementById( "video" );
iframe.src = element.getAttribute( "href" );
video.style.display = "block" ;
const webSeriesData = document.getElementById( "webSeriesData" );
const tmdbApiKey = "your-tmdb-api-key" ;
const imdbID = element.getAttribute( "IMDB" );
Pace.restart();
scrollToTop();
// hide information
window.dispatchEvent( new PopStateEvent( "popstate" ));
// clearing episodes list box for another series
if (
element.getAttribute( "isWebSeries" ) == "false" &&
element.className == "links"
) {
webSeriesData.innerHTML = "" ;
}
// setting page title
if (element.getAttribute( "title" ) !== "" ) {
document.title = element.getAttribute( "title" );
}
// highlight selected webseries episode
if (element.className.includes( "episode" )) {
episodeHighlight(element.getAttribute( "cssidentification" ));
console.log( "clicked" );
}
// Displaying webseries episode
if (element.getAttribute( "isWebSeries" ) == "true" ) {
webSeriesData.innerHTML = "" ;
async function printEpisodes() {
// First, get the show's TMDB id based on its IMDb id
const response = await fetch(
`...key=${tmdbApiKey}&language=
en-US&external_source=imdb_id`
);
const data = await response.json();
const showId = data.tv_results[0].id;
// Next, get information about the show's seasons
const seasonsData = await fetch(
`...=${tmdbApiKey}&language=en-US`
);
const seasonsDataJSON = await seasonsData.json();
const numberOfSeasons = seasonsDataJSON.number_of_seasons;
webSeriesData.innerHTML += `<h2>Seasons:</h2>`;
for (
let seasonNumber = 1;
seasonNumber <= numberOfSeasons;
seasonNumber++
) {
webSeriesData.innerHTML += `<h3>Season
${seasonNumber}:</h3><br>`;
let episodeContainer = document.createElement( "div" );
episodeContainer.classList.add( "episode-container" );
let episodesData = "" ;
// Get information about episodes in the season
const episodesDataResponse = await fetch(
`...=${tmdbApiKey}&language=en-US`
);
const episodesDataJSON = await episodesDataResponse.json();
for (const episode of episodesDataJSON.episodes) {
const episodeNumber = episode.episode_number;
let formatedEpisodeNumber =
episodeNumber.toLocaleString( "en-US" , {
minimumIntegerDigits: 2,
useGrouping: false ,
});
episodesData += `<a class= "episodes" title= "${seasonsDataJSON.name + " : E " +
formatedEpisodeNumber + " . " + episode.name}" cssidentification= "s${seasonNumber}e${episodeNumber}" url= "imdb=${imdbID}&season=${seasonNumber}
&episode=${episodeNumber}&title=${
seasonsDataJSON.name.replace(/ /g, " _ ") +
" _E " + formatedEpisodeNumber + " _ "
+ episode.name.replace(/ /g, " _ ")}" onClick= "event.preventDefault();setVideo(this);setUrl(this); " href= "...=${seasonNumber}&e=${episodeNumber}" >
E${formatedEpisodeNumber}. ${episode.name}</a>`;
}
episodeContainer.innerHTML = episodesData;
webSeriesData.appendChild(episodeContainer);
episodeHighlight();
}
// Highlighting Selected Episodes as per url
let searchParams = new URLSearchParams(window.location.search);
let season = searchParams.get( "season" );
let episode = searchParams.get( "episode" );
if (season && episode) {
document
.querySelector(`a[cssIdentification=
"s${season}e${episode}" ]`)
.click();
} else if (season && !episode) {
document.querySelector(`a[cssIdentification= "s${season}e1" ]`)
.click();
} else {
document.querySelector(`a[cssIdentification= "s1e1" ]`).click();
}
}
printEpisodes();
} else {
}
highlightCards();
// returning false so that anchor tag do not work as link
return false ;
} |
Output: Finally, our web app will look like this:
The video player will look like this:
Get the full source code from this GitHub repository. You can view the live demo of the web app here.