Play video at specific interval of time using javascript and post messege - javascript

I have a simple app which I have three different videos, I want each video to play at certain time. As example:
First video to play.
between 5:00 AM and 10:00 AM.
Second video to play.
between 10:00 AM and 22:00 PM.
Third video to play.
between 22:00 PM and 5:00 AM.
So assume if a user visited my app around 9:00 AM. It should automatically play the first video. If the user visit around 11: 00 AM, the second video plays, and etc.
I want a function to run function at set interval only at certain time of the day using javascript and the postMessage function,
Here is my solution:
app.js
var welcomeMovie1 = "http://mirrors.standaloneinstaller.com/video-sample/jellyfish-25-mbps-hd-hevc.mp4";
var welcomeMovie2 = "http://mirrors.standaloneinstaller.com/video-sample/TRA3106.mp4"
var welcomeMovie3 = "http://mirrors.standaloneinstaller.com/video-sample/Panasonic_HDC_TM_700_P_50i.mp4";
var messageTime;
//function to play a video1 to iframe using post messages
function welcomeMessage1() {
document.getElementById('videoframe').contentWindow.postMessage(
JSON.stringify({
event: 'playVideo(welcomeMovie1)'
}),
'*'
)
}
//function to play a video2 to iframe using post messages
function welcomeMessage2() {
document.getElementById('videoframe').contentWindow.postMessage(
JSON.stringify({
event: 'playVideo(welcomeMovie2)'
}),
'*'
)
}
//function to play a video3 to iframe using post messages
function welcomeMessage3() {
document.getElementById('videoframe').contentWindow.postMessage(
JSON.stringify({
event: 'playVideo(welcomeMovie2)'
}),
'*'
)
}
//function to play a video1 to iframe using post messages at Specific time
setInterval(function() {
var messageTime = new Date().getHours();
if (messageTime >= 5 && messageTime < 10) {
welcomeMessage1();
console.log(welcomeMessage2());
}
}, 1000 * 60);
//function to play a video2 to iframe using post messages at Specific time
setInterval(function() {
var messageTime = new Date().getHours();
console.log(date.toLocaleString('en-GB'));
if (messageTime >= 10 && messageTime < 22) {
welcomeMessage2();
console.log(welcomeMessage2());
}
}, 1000 * 60);
//function to play a video3 to iframe using post messages at Specific time
setInterval(function() {
var messageTime = new Date().getHours();
if (messageTime >= 22 && messageTime < 5) {
welcomeMessage3();
}
}, 1000 * 60);
// promise function to create custom video controls and play functions
function playVideo(src) {
$("#playervideo").attr("src", src);
$("#playervideo")[0].muted = false;
if (autoplay == true) {
var playPromise = $("#playervideo")[0].play();
if (playPromise !== undefined) {
playPromise.then(function() {}).catch(function() {
if (autoplay == true) {
$("#video-unmute-button").addClass("show");
$("#playervideo")[0].muted = true;
var playPromise2 = $("#playervideo")[0].play();
playPromise2.then(function() {
}).catch(function() {
$("#video-start-button").addClass("show");
$("#video-start-button").on("click", function() {
$("#playervideo")[0].muted = false;
$("#playervideo")[0].play();
$("#video-start-button").removeClass("show");
});
});
console.log("pause force");
} else {
}
});
} else {}
} else {
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Video Frame</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<iframe id="videoframe" src="videoframe.html"></iframe>
<br/>
<!-- <input id="name" type="text"/> -->
</body>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://code.createjs.com/1.0.0/createjs.min.js"></script>
<script src="js/app.js" type="text/javascript"></script>
<script src="js/form.js" type="text/javascript"></script>
</html>
Here is plunker for full demo: demo
Unfortunately it's not working,
What do I need to change in my code to get what I want?

<iframe> & <video>
Autoplay
Autoplay ain't what it used to be. There's too many restrictions and various criteria involved in getting a <video> tag to autoplay. Here's what was needed:
<video> tag needs [muted] and [autoplay] attributes
<video ... muted autoplay></video>
<iframe> tag needs [allow="autoplay"] attribute. Full screen is optional
<iframe ... allowfullscreen allow="autoplay; fullscreen"></iframe>
In the demo below loadVideo() is the function that loads a MP4 file to the <video> tag's [src] according to the current time. Autoloading media from an <iframe> is tricky because they are one of the last of the DOM content to load. It's best to run the function from the child page (videoframe.html) in an IIFE (Immediately-invoked Function Expression).
(function() {
loadVideo();
})();
Promises
In order to invoke play() method, you'll need to use the Promise API. This is another instance when something works and engineers want to overcomplicate it.
async function promisePlay() {
try {
await document.querySelector('video').play();
} catch (err) {
...
}
}
postMessage
For cross-domain communication using the postMessage API via <iframe>, the developer must have ownership of both domains. Ownership doesn't necessarily mean full administrative privileges, just enough so that both pages can actually be edited. There are some APIs that'll meet you halfway like YouTube and Vimeo as well.
Basically the parent page (index.html) will send a message:
window.frames[0].postMessage(data, origin);
window.frames[0] will get the first <iframe> and access it's window content, an equivalent to: document.querySelector('iframe').contentWindow;.
data is just a string.
origin is usually the location.protocol and location.hostname or location.origin of the parent page (index.html): https://www.example.com.
The child page (videoframe.html) receives the data (just a typical string) by listening for the message event on it's Window Object:
window.addEventListener("message", callback);
Most examples show how a message is sent and received, and the result of the message being displayed on the child page -- lame 🙄. Here's what a callback would look like if it were actually useful:
function callback(event) {
var string = event.data;
// Optional-------------------------
var from = event.origin;
if (from !== 'https://www.example.com') {
document.querySelector('#displayMsg').textContent = `MESSAGE REJECTED`;
return;
}
//----------------------------------
if (string === "play") {
promisePlay();
} else if (string === "pause") {
document.querySelector('video').pause();
} else if (string === "stop") {
document.querySelector('video').pause();
document.querySelector('video').currentTime = 0;
} else {
document.querySelector('#displayMsg').textContent = `ERROR: ${string} is not a command.`;
}
}
Plunker
Demo
index.html
Note: The following Stack Snippet does not function properly due to SO restriction on <iframe> use. For a fully functional demo go to this Plunker.
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
font: 400 16px/1.5 Consolas;
overflow: hidden;
}
main {
width: 100%;
height: auto;
padding: 10px;
}
section {
height: 0;
width: 100%;
position: relative;
padding-bottom: 56.25%;
margin: 15px auto 5px;
}
fieldset {
width: fit-content;
padding: 5px;
}
iframe {
height: 100%;
width: 100%;
overflow: hidden;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
select,
button {
font: inherit;
padding: 0 3px;
line-height: 1.2;
}
#msg {
position: absolute;
z-index: 1;
background: rgba(0, 0, 0, 0.5);
}
#time,
#rX {
display: block;
float: left;
color: gold;
padding: 0 5px;
width: 70px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Video Frame</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<section>
<iframe src="https://run.plnkr.co/preview/cjpwrvczh00073a5v3m08unmw/videoframe.html" width='100%' height='100%' scrolling='no' frameborder='0' allowfullscreen allow="autoplay; fullscreen"></iframe>
</section>
<form id='control'>
<fieldset>
<select id='tX'>
<option value='Timeslot'>Select</option>
<optgroup label='Command'>
<option>Play</option>
<option>Pause</option>
<option>Stop</option>
</optgroup>
<optgroup label='Load Media'>
<option>Video 1</option>
<option>Video 2</option>
<option>Video 3</option>
</optgroup>
<optgroup label="Test">
<option>Messages</option>
<option>Controls</option>
</optgroup>
</select>
<button>Send</button>
</fieldset>
</form>
</main>
<script>
window.onload = function(e) {
var ctrl = document.forms.control;
var cX = ctrl.elements;
var tX = cX.tX;
ctrl.addEventListener('submit', function(e) {
e.preventDefault();
window.frames[0].postMessage(tX.value, "https://" + location.hostname);
console.log(tX.value);
});
};
</script>
</body>
</html>
videoframe.html
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
font: 400 16px/1.5 Consolas;
overflow: hidden;
}
main {
width: 100%;
height: auto;
padding: 10px;
}
section {
height: 0;
width: 100%;
position: relative;
padding-bottom: 56.25%;
margin: 15px auto 5px;
}
fieldset {
width: fit-content;
padding: 5px;
}
iframe {
height: 100%;
width: 100%;
overflow: hidden;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
select,
button {
font: inherit;
padding: 0 3px;
line-height: 1.2;
}
#msg {
position: absolute;
z-index: 1;
background: rgba(0, 0, 0, 0.5);
}
#time,
#rX {
display: block;
float: left;
color: gold;
padding: 0 5px;
width: 70px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Video iframe</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<aside id='msg'>
<output id='rX'></output>
<time id='time'></time>
</aside>
<video id='vX' src='about:blank' width='96%' muted autoplay></video>
<script>
var v = document.getElementById('vX');
var vid =
'https://storage04.dropshots.com/photos6000/photos/1381926/20170326/';
var r = document.getElementById('rX');
var t = document.getElementById('time');
(function() {
loadVideo();
})();
window.addEventListener("message", rXMsg);
function rXMsg(e) {
var msg = e.data;
switch (msg) {
case 'Play':
playMedia();
break;
case 'Pause':
v.pause();
break;
case 'Stop':
v.pause();
v.currentTime = 0;
break;
case 'Video 1':
v.src = vid + '005609.mp4';
v.load();
break;
case 'Video 2':
v.src = vid + '005610.mp4';
v.load();
break;
case 'Video 3':
v.src = vid + '005612.mp4';
v.load();
break;
case 'Messages':
toggleAttr('#msg', 'hidden');
break;
case 'Controls':
toggleAttr('#vX', 'controls');
break;
default:
loadVideo();
break;
}
stamp(msg);
}
function loadVideo() {
var hrs = stamp();
// 05:00 - 09:59
if (hrs >= 5 && hrs < 10) {
v.src = vid + '005609.mp4';
v.load();
}
// 10:00 - 21:59
else if (hrs >= 10 && hrs < 22) {
v.src = vid + '005610.mp4';
v.load();
}
// 22:00 - 04:59
else {
v.src = vid + '005612.mp4';
v.load();
}
stamp('Autoload');
}
async function playMedia() {
try {
await v.play();
} catch (err) {
stamp('Promise Rejected');
}
}
function toggleAttr(selector, attr) {
var node = document.querySelector(selector);
var prop = node.getAttribute(attr);
if (!prop) {
node.setAttribute(attr, true);
} else {
node.removeAttribute(attr);
}
}
function stamp(str) {
var now = new Date();
var hrs = now.getHours();
var min = now.getMinutes();
var sec = now.getSeconds();
var h = hrs > 9 ? "" + hrs : "0" + hrs;
var m = min > 9 ? "" + min : "0" + min;
var s = sec > 9 ? "" + sec : "0" + sec;
var time = h + ":" + m + ":" + s;
r.textContent = str;
t.textContent = time;
return hrs;
}
</script>
</body>

There is no need to use setInterval; you only need to use an if statement or a switch case.
I removed the setInterval code and made one if statement. In the last condition, you need to change the double ampersand (&&/AND) to || (OR) - the (>22 OR <5)- otherwise it doesn't make sense. I tested the following by adjusting my system clock, it seems to work.
Here's a fiddle
Happy holidays!
var welcomeMovie1 = "http://mirrors.standaloneinstaller.com/video-sample/jellyfish-25-mbps-hd-hevc.mp4";
var welcomeMovie2 = "http://mirrors.standaloneinstaller.com/video-sample/TRA3106.mp4"
var welcomeMovie3 = "http://mirrors.standaloneinstaller.com/video-sample/Panasonic_HDC_TM_700_P_50i.mp4";
var messageTime = new Date().getHours();
var welcomeMsg = "";
var vid = " ";
//console.log(messageTime);
if (messageTime >= 5 && messageTime <= 10) {
welcomeMsg = "early bird";
vid = welcomeMovie1;
//console.log(welcomeMessage2);
}
else
if (messageTime >= 10 && messageTime < 22) {
welcomeMsg = "middle of day";
vid = welcomeMovie2;
//console.log(welcomeMessage2());
}
else
if (messageTime >= 22 || messageTime < 5) {
welcomeMsg = "night owl";
vid = welcomeMovie3;
}
////}, 1000 * 60);
playVideo(vid);
console.log("Hello! Your welcome message is " + welcomeMsg + " " + vid)
// promise functionb to create custom video controls and play functions
function playVideo(src) {
console.log("Hello! Your welcome message is " + welcomeMsg + " " + vid)
$("#playervideo").attr("src", src);
$("#playervideo")[0].muted = false;
if (autoplay == true) {
var playPromise = $("#playervideo")[0].play();
if (playPromise !== undefined) {
playPromise.then(function() {}).catch(function() {
if (autoplay == true) {
$("#video-unmute-button").addClass("show");
$("#playervideo")[0].muted = true;
var playPromise2 = $("#playervideo")[0].play();
playPromise2.then(function() {
}).catch(function() {
$("#video-start-button").addClass("show");
$("#video-start-button").on("click", function() {
$("#playervideo")[0].muted = false;
$("#playervideo")[0].play();
$("#video-start-button").removeClass("show");
});
});
console.log("pause force");
} else {
}
});
} else {}
} else {
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<iframe id="playervideo" controls src=" ">
</iframe>

Related

How do i get the date counter to stop running in background even while paused? Any and all help is appreciated

I have a date counter with play/pause button that works great, however, during pause the counter continues to run in the background.
To see what I mean, press pause, wait 10 seconds, press play and you will see the date has advanced 1 or 2 months, not to the next day. I am grateful for any help. My code is below.
var virtualOrigin = Date.parse("2020-01-01"),
realOrigin = Date.now(),
factor = 862350;
function getVirtual(time) {
return new Date(virtualOrigin + (time - realOrigin) * factor);
}
function format(time) {
var month = time.getMonth() + 1;
var day = time.getDate();
if (month < 10) {
month = '0' + month;
}
if (day < 10) {
day = '0' + day;
}
return (month) +
"-" + day +
"-" + time.getFullYear();
}
var output = document.getElementById("txt");
var t = 0;
var flagTimer = 'startTime()';
function pause() {
if (flagTimer == 'startTime()') {
clearTimeout(t);
document.getElementById('Pause').value = "Play";
flagTimer = 'pause';
} else {
flagTimer = 'startTime()';
document.getElementById('Pause').value = "Pause";
startTime();
}
}
function startTime() {
var now = new Date();
var display = getVirtual(now);
output.innerText = format(display);
t = setTimeout(startTime, 1000 / factor - (now.getMilliseconds() %
(1000 / factor)));
}
function clickEvent() {
pause();
}
.txt {
color: orange;
margin-left: 46%;
margin-top: 10%;
position: absolute;
z-index: 300;
}
#Pause {
margin-left: 47.6%;
margin-top: 10%;
border: 2px solid orange;
color: blue;
display: block;
width: 55px;
text-align: center;
}
#Pause:hover {
background-color: orange;
color: white;
border: 2px solid lightblue;
}
#toggle-animation {
margin-left: 45.5%;
margin-top: 10%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>timer8</title>
<meta charset=UTF-8>
</head>
<body onload="startTime()">
<input type="button" id="Pause" class="toggle-animation" value="Pause" onclick="clickEvent();" />
<div id="txt" class="txt"></div>
</body>
</html>
Your function to calculate the virtual date:
function getVirtual(time) {
return new Date( virtualOrigin + (time - realOrigin) * factor );
}
... calculates it based on the difference between the current time and page load time, regardless of whether you have paused or not.
You could fix this by:
when pausing, updating virtualOrigin to the current virtual datetime
in your getVirtual(time) function, only adding the difference when your timer is unpaused
when unpausing, updating realOrigin to the current real datetime.

ajax - How can I build a chat with Ajax and settimeout without the process taking a lot of virtual memory?

I'm trying to build a chat based on AJAX that receives data every second by settimeout.
I wrote a basic code where there is a number that increases each second of the number obtained from the php page2.
I checked it from my computer by opening the file in 3 different browsers and saw that it takes a lot of virtual memory from the server. My fear is what will happen if I build a real chat in this format and 50 people simultaneously enter?
I know that setTimeout takes a lot of memory, is there any other way to build chat? Or can I improve what I did?
I would be very happy to answer!
that's what i did:
<body>
<h1 id='number'>0</h1>
<script>
function ajax() {
if (window.XMLHttpRequest) {
var a = new XMLHttpRequest()
} else {
var a = new ActivXObject('Microsoft.XMLHTTP')
}
return a
}
var settime = 1000;
var myTime;
ajaxMain();
function ajaxMain() {
xmlhttp = ajax();
xmlhttp.onreadystatechange = function() {
if (((xmlhttp.readyState == 4) || (xmlhttp.readyState == 0)) && (xmlhttp.status == 200)) {
if (xmlhttp.responseText) {
id('mmm').innerHTML = (xmlhttp.responseText) * 1 + (id('number').innerHTML) * 1;
myTime = setTimeout('ajaxMain()', settime)
}
} else {
if (xmlhttp.responseText.match(/^\<\!/)) {
clearTimeout(myTime);
myTime = setTimeout('ajaxMain()', settime)
}
}
}
xmlhttp.open('GET', 'page2.php', true)
xmlhttp.send()
}
</script>
</body>
</html>
page2.php:
<?php
echo 1
?>
Thier is a full guide how to create an AJAX based chat system in PHP by Ashraf Gheith,
I'll quote:
CREATE TABLE `chat` (
`id` INT(9) NOT NULL AUTO_INCREMENT ,
`usrname` VARCHAR(255) NOT NULL ,
`color` VARCHAR(6) NOT NULL ,
`chattext` TEXT NOT NULL ,
`chattime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
PRIMARY KEY (`id`)
) ENGINE = MyISAM CHARACTER SET utf8 COLLATE utf8_unicode_ci;
var lastTimeID = 0;
$(document).ready(function() {
$('#btnSend').click( function() {
sendChatText();
$('#chatInput').val("");
});
startChat();
});
function startChat(){
setInterval( function() { getChatText(); }, 2000);
}
function getChatText() {
$.ajax({
type: "GET",
url: "/refresh.php?lastTimeID=" + lastTimeID
}).done( function( data )
{
var jsonData = JSON.parse(data);
var jsonLength = jsonData.results.length;
var html = "";
for (var i = 0; i < jsonLength; i++) {
var result = jsonData.results[i];
html += '<div style="color:#' + result.color + '">(' + result.chattime + ') <b>' + result.usrname +'</b>: ' + result.chattext + '</div>';
lastTimeID = result.id;
}
$('#view_ajax').append(html);
});
}
function sendChatText(){
var chatInput = $('#chatInput').val();
if(chatInput != ""){
$.ajax({
type: "GET",
url: "/submit.php?chattext=" + encodeURIComponent( chatInput )
});
}
}
body{
margin: 0;
padding: 0;
}
#view_ajax {
display: block;
overflow: auto;
width: 500px;
height: 300px;
border: 1px solid #333;
margin: 0 auto;
margin-top: 20px;
}
#ajaxForm{
display: block;
margin: 0 auto;
width: 500px;
height: 50px;
margin-top: 10px;
}
#chatInput{
width: 454px;
}
<html>
<head>
<title>Chat Room Example</title>
<script src="js/jquery.min.js"></script>
<script src="js/main.js"></script>
<link rel="stylesheet" href="css/main.css" />
</head>
<body>
<div id="view_ajax"></div>
<div id="ajaxForm">
<input type="text" id="chatInput" /><input type="button" value="Send" id="btnSend" />
</div>
</body>
</html>
The full guide will be on this link

simple animation in java script

I'm trying to learn Java Script Animations and I found really good examples on this site: http://javascript.info/tutorial/animation#maths-the-function-of-progress-delta
But the problem is, as a beginner, I don't understand how the functions and objects work with each other.
Question 01
I copied the example "Let’s create a movement animation on it’s base:" But my version does not work.
<!DOCTYPE HTML>
<html>
<head>
<style>
.example_path{
position: relative;
width: 600px;
height: 100px;
border-style: solid;
border-width: 5px;
}
.example_block{
position: absolute;
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
</head>
<body>
<div onclick="move(this.children[0])" class="example_path">
<div class="example_block"></div>
</div>
<script>
function move(element, delta, duration) {
var to = 500
animate({
delay: 10,
duration: duration || 1000, // 1 sec by default
delta: delta,
step: function(delta) {
element.style.left = to*delta + "px"
}
})
}
</script>
</body>
</html>
output console: ReferenceError: animate is not defined
Does anyone know what the problem is?
Question 02
My second wish is, to integrate the easeInOut function
function makeEaseInOut(delta) {
return function(progress) {
if (progress < .5)
return delta(2*progress) / 2
else
return (2 - delta(2*(1-progress))) / 2
}
}
bounceEaseInOut = makeEaseInOut(bounce)
How can I link both code snippets? The code is also from this page: http://javascript.info/tutorial/animation#maths-the-function-of-progress-delta
Add animate and makeEaseInOut into your script tag then you can use them. You may want to include the functions in a separate JavaScript file eventually.
<script>
function animate(opts) {
var start = new Date
var id = setInterval(function() {
var timePassed = new Date - start
var progress = timePassed / opts.duration
if (progress > 1) progress = 1
var delta = opts.delta(progress)
opts.step(delta)
if (progress == 1) {
clearInterval(id)
}
}, opts.delay || 10)
}
function makeEaseInOut(delta) {
return function(progress) {
if (progress < .5)
return delta(2*progress) / 2
else
return (2 - delta(2*(1-progress))) / 2
}
}
bounceEaseInOut = makeEaseInOut(bounce)
</script>
that's what I tried.
I still have problems.
output console: delta is not a function. bounce is not a function.
I know I have to learn more about creating functions. But right now I'm not that good to solve the problem.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
.example_path{
position: relative;
width: 600px;
height: 100px;
border-style: solid;
border-width: 5px;
}
.example_block{
position: absolute;
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
<script>
function move(element, delta, duration) {
var to = 500;
animate({
delay: 10,
duration: duration || 1000, // 1 sec by default
delta: delta,
step: function(delta) {
element.style.left = to*delta + "px"
}
});
}
function animate(opts) {
var start = new Date;
var id = setInterval(function() {
var timePassed = new Date - start;
var progress = timePassed / opts.duration;
if (progress > 1) progress = 1
var delta = opts.delta(progress);
opts.step(delta);
if (progress == 1) {
clearInterval(id);
}
}, opts.delay || 10);
}
function makeEaseInOut(delta) {
return function(progress) {
if (progress < .5)
return delta(2*progress)/2;
else
return (2 - delta(2*(1-progress)))/2;
};
}
varbounceEaseInOut = makeEaseInOut(bounce);
</script>
</head>
<body>
<div onclick="move(this.children[0], makeEaseInOut(bounce), 3000)" class="example_path">
<div class="example_block"></div>
</div>
</body>
</html>
I've made a very simple animation using javascript, hope it helps, try to "Run code snippet" for better understanding.
/*JavaScript*/
function myMove() {
var elem = document.getElementById("animate");
var pos = 0;
var id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
function Back() {
var elem1 = document.getElementById("animate");
var id1 = setInterval(frame2, 5);
var pos1 = 350;
function frame2() {
if (pos1 == 0) {
clearInterval(id1);
} else {
pos1--;
elem1.style.top = pos1 + 'px';
elem1.style.left = pos1 + 'px';
}
}
}
/*CSS*/
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
/*HTML*/
<button onclick="myMove()">Click Me</button>
<button onclick="Back()"> roll back</button>
<div id ="container">
<div id ="animate"></div>
</div>

Scroll in samsung Smart TV

I have articles to display in an application of smart TV (coding JavaScript) but unfortunately, it shows only the first few onces while all the rest of them stay down hidden. Is there any way how to scroll in Samsung Smart TV ?
if you are using divs or list to display data than you can easily hide a list or Div using jquery on key press.
scrollBy and scrollTo work fine on samsung smart tv (not on lg). You did not describe your problem well enough, but I guess all you need to bind up/down keys to one of the scroll APIs.
I recommend using isscrolljs instead of using scrollBy and scrollTo, as it works well on both samsung and lg. smarttvjs also uses it.
var widgetAPI = new Common.API.Widget();
var tvKey = new Common.API.TVKeyValue();
var InitH = 440 -10;
var InitTop = 50;
var MaxTop;
var interT = null, interD = null;
var d;
var t;
var prevT = null;
var Main =
{
};
Main.onLoad = function()
{
// Enable key event processing
this.enableKeys();
widgetAPI.sendReadyEvent();
MaxTop = $("#Content").position().top - (parseInt($("#Content").css("height"))- InitH);
alert($("#Content").position().top);
alert(MaxTop);
};
Main.onUnload = function()
{
};
Main.enableKeys = function()
{
document.getElementById("anchor").focus();
};
Main.keyDown = function()
{
var keyCode = event.keyCode;
alert("Key pressed: " + keyCode);
switch(keyCode)
{
case tvKey.KEY_RETURN:
case tvKey.KEY_PANEL_RETURN:
alert("RETURN");
widgetAPI.sendReturnEvent();
break;
case tvKey.KEY_LEFT:
alert("LEFT");
break;
case tvKey.KEY_RIGHT:
alert("RIGHT");
break;
case tvKey.KEY_UP:
alert("UP");
interTop();
d = new Date();
t =parseInt((d.getTime()%10000)/1000);
alert(t+" ---------" );
//alert(scroll);
//Math.abs(t-prevT)>=3 && Math.abs(t-prevT)<=7
if(($("#Content").position().top<InitTop && t!=prevT) || prevT == null){
$("#Content").css("top",$("#Content").position().top+50+"px");
prevT = t;
}else if($("#Content").position().top>InitTop){
$("#Content").css("top",InitTop+"px");
}
break;
case tvKey.KEY_DOWN:
alert("DOWN");
interDown();
d = new Date();
t =parseInt((d.getTime()%10000)/1000);
alert(t+" ---------" );
//alert(scroll);
//Math.abs(t-prevT)>=3 && Math.abs(t-prevT)<=7
if(($("#Content").position().top>MaxTop && t!=prevT) || prevT == null){
$("#Content").css("top",$("#Content").position().top-50+"px");
prevT = t;
}else if($("#Content").position().top<MaxTop){
$("#Content").css("top",MaxTop+"px");
}
break;
case tvKey.KEY_ENTER:
case tvKey.KEY_PANEL_ENTER:
alert("ENTER");
alert($("#Content").css("height"));
alert($("#Content").position().top);
break;
default:
alert("Unhandled key");
break;
}
};
function interTop(){
clearInterval(interD);
interD = null;
if(interT == null){
interT = setInterval(function(){if($("#Content").position().top>InitTop){
$("#Content").css("top",InitTop+"px");
}
},500);
}
}
function interDown(){
clearInterval(interT);
interT = null;
if(interD == null){
interD = setInterval(function(){if($("#Content").position().top<MaxTop){
$("#Content").css("top",MaxTop+"px");
}
},500);
}
}
var widgetAPI = new Common.API.Widget();
var tvKey = new Common.API.TVKeyValue();
var total_item = 3, current_item = 0;
//var variable = Document.getElementById("Content");
var Main =
{
};
Main.onLoad = function()
{
// Enable key event processing
this.enableKeys();
widgetAPI.sendReadyEvent();
navigation("DOWN");
fetchNews();
///////////////////////////////////
/* L'appel du Parser à compléter */
/* L'appel du Parser à compléter */
/* L'appel du Parser à compléter */
///////////////////////////////////
};
Main.onUnload = function()
{
};
Main.enableKeys = function()
{
document.getElementById("anchor").focus();
};
Main.keyDown = function()
{
var keyCode = event.keyCode;
alert("Key pressed: " + keyCode);
switch(keyCode)
{
case tvKey.KEY_RETURN:
case tvKey.KEY_PANEL_RETURN:
alert("RETURN");
widgetAPI.blockNavigation(event);
parent.location = "index.html";
break;
case tvKey.KEY_LEFT:
alert("LEFT");
break;
case tvKey.KEY_RIGHT:
alert("RIGHT");
break;
case tvKey.KEY_UP:
alert("UP");
//navigation("UP");
break;
case tvKey.KEY_DOWN:
alert("DOWN");
//navigation("DOWN");
break;
case tvKey.KEY_ENTER:
case tvKey.KEY_PANEL_ENTER:
alert("ENTER");
//gotoPage();
break;
default:
alert("Unhandled key");
break;
}
};
function navigation(direction){
$("#btn_"+current_item).removeClass("selected_btn");
if(direction == "UP"){
if(current_item == 1)
current_item = total_item;
else
current_item--;
}else if(direction == "DOWN"){
if(current_item == total_item)
current_item = 1;
else
current_item++;
}
$("#btn_"+current_item).addClass("selected_btn");
}
function gotoPage(){
switch(current_item){
//case 1: parent.location = "gallery.html"; break;
case 2: parent.location = "news.html"; break;
case 3: parent.location = "about.html"; break;
}
}
function fetchNews(){
if ( ParserNews.init()) {
ParserNews.dataReceivedCallback = function() {
prepareNewsList();
};
ParserNews.fetchDatas();
}
};
function prepareNewsList(){
var i;
for(i=0; i<DataNews.getCount(); i++){
$("<div/>").addClass("newsItem").html('<div class="title">'+DataNews.getTitle(i)+'</div></br><div><img src ="'+DataNews.getDate(i)+'"></div>').appendTo($("body"));
}
alert(DataNews.getTitle(3)) ;
alert(DataNews.getMiservices(3)) ;
alert(DataNews.getCount());
}
// This is the CSS file
* {
padding: 0;
margin: 0;
border: 0;
}
/* Layout */
body {
width: 1280px;
height: 720px;
background-image: url("../img/backk.jpg");
position: fixed;
}
.newsItem {
padding: 10px;
color: #fff;
width: 1250px;
height: 100px;
margin-bottom: 10px;
margin-left: 80px;
background-color: #388e8e;
}
.title {
color: #87d2ef;
font-size: 20px;
}
.description {
color: #fff;
font-size: 15px;
}
.img {
width: 50px;
height: 60px;
position: absolute;
left: 50px;
top: 50px;
}
.text {
position: absolute;
width: 500px;
height: 400px;
left: 400px;
top: 50px;
font-size: 25px;
color: #fff;
}
#Content {
-webkit-transition: top 1s ease-in-out;
}
.transitions .top {
top: 0;
}
.transitions .bottom {
top: -70px;
}
// Finally HTML file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Tunisie</title>
<!-- TODO : Common API -->
<script type="text/javascript" language="javascript" src="$MANAGER_WIDGET/Common/API/Widget.js"></script>
<script type="text/javascript" language="javascript" src="$MANAGER_WIDGET/Common/API/TVKeyValue.js"></script>
<script type="text/javascript" language="javascript" src="$MANAGER_WIDGET/Common/jquery.js"></script>
<!-- TODO : Javascript code -->
<script type="text/javascript" src="app/javascript/Parser_News.js"></script>
<script type="text/javascript" src="app/javascript/Data_News.js"></script>
<script language="javascript" type="text/javascript" src="app/javascript/News.js"></script>
<script language="javascript" type="text/javascript" src="app/javascript/testScroll.js"></script>
<!-- TODO : Style sheets code -->
<link rel="stylesheet" href="app/stylesheets/testScroll.css" type="text/css">
<!-- TODO: Plugins -->
</head>
<body onload="Main.onLoad();" onunload="Main.onUnload();">
<!-- Dummy anchor as focus for key events -->
<div class="newsItem" id="Content" style="width:100%; top:50px; left:100px; border:solid 1px #000000; position:fixed;">
</div>
</body>
</html>

How to play only the audio of a Youtube video using HTML 5?

Is it possible to play only the audio from a YouTube video using HTML 5 and Javascript?
UPDATE 2022
webm formats added for demo. You can always check for console log and add all formats needed.
UPDATE 2021
You can parse Youtube HTML page for all streams available for this particular video and extract audio only streams.
Here is an example with public Google Image proxy (but you can use any free or your own CORS proxy):
var vid = "3r_Z5AYJJd4",
audio_streams = {},
audio_tag = document.getElementById('youtube');
fetch("https://images" + ~~(Math.random() * 33) + "-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=" + encodeURIComponent("https://www.youtube.com/watch?hl=en&v=" + vid)).then(response => {
if (response.ok) {
response.text().then(data => {
var regex = /(?:ytplayer\.config\s*=\s*|ytInitialPlayerResponse\s?=\s?)(.+?)(?:;var|;\(function|\)?;\s*if|;\s*if|;\s*ytplayer\.|;\s*<\/script)/gmsu;
data = data.split('window.getPageData')[0];
data = data.replace('ytInitialPlayerResponse = null', '');
data = data.replace('ytInitialPlayerResponse=window.ytInitialPlayerResponse', '');
data = data.replace('ytplayer.config={args:{raw_player_response:ytInitialPlayerResponse}};', '');
var matches = regex.exec(data);
var data = matches && matches.length > 1 ? JSON.parse(matches[1]) : false;
console.log(data);
var streams = [],
result = {};
if (data.streamingData) {
if (data.streamingData.adaptiveFormats) {
streams = streams.concat(data.streamingData.adaptiveFormats);
}
if (data.streamingData.formats) {
streams = streams.concat(data.streamingData.formats);
}
} else {
return false;
}
streams.forEach(function(stream, n) {
var itag = stream.itag * 1,
quality = false;
console.log(stream);
switch (itag) {
case 139:
quality = "48kbps";
break;
case 140:
quality = "128kbps";
break;
case 141:
quality = "256kbps";
break;
case 249:
quality = "webm_l";
break;
case 250:
quality = "webm_m";
break;
case 251:
quality = "webm_h";
break;
}
if (quality) audio_streams[quality] = stream.url;
});
console.log(audio_streams);
audio_tag.src = audio_streams['256kbps'] || audio_streams['128kbps'] || audio_streams['48kbps'];
audio_tag.play();
})
}
});
<audio id="youtube" autoplay controls loop></audio>
Doesn't work for all videos, very depends on monetization settings or something like that.
Embed the video player and use CSS to hide the video. If you do it properly you may even be able to hide only the video and not the controls below it.
However, I'd recommend against it, because it will be a violation of YouTube TOS. Use your own server instead if you really want to play only audio.
UPDATED FOR 2020
It seems in Septeber 2019, YouTube updated the values that are returned by get_video_info.
Rather than data.url_encoded_fmt_stream_map and data.adaptive_fmts (as used in the other older examples) now we are looking for for data.formats and data.adaptiveFormats.
Anyways here is what you are all here for some code that loads a YouTube video into an <audio> element. Try it on CodePen
// YouTube video ID
var videoID = "CMNry4PE93Y";
// Fetch video info (using a proxy to avoid CORS errors)
fetch('https://cors-anywhere.herokuapp.com/' + "https://www.youtube.com/get_video_info?video_id=" + videoID).then(response => {
if (response.ok) {
response.text().then(ytData => {
// parse response to find audio info
var ytData = parse_str(ytData);
var getAdaptiveFormats = JSON.parse(ytData.player_response).streamingData.adaptiveFormats;
var findAudioInfo = getAdaptiveFormats.findIndex(obj => obj.audioQuality);
// get the URL for the audio file
var audioURL = getAdaptiveFormats[findAudioInfo].url;
// update the <audio> element src
var youtubeAudio = document.getElementById('youtube');
youtubeAudio.src = audioURL;
});
}
});
function parse_str(str) {
return str.split('&').reduce(function(params, param) {
var paramSplit = param.split('=').map(function(value) {
return decodeURIComponent(value.replace('+', ' '));
});
params[paramSplit[0]] = paramSplit[1];
return params;
}, {});
}
<audio id="youtube" controls></audio>
This may be an old post but people could still be searching for this so here you go:
<div style="position:relative;width:267px;height:25px;overflow:hidden;">
<div style="position:absolute;top:-276px;left:-5px">
<iframe width="300" height="300"
src="https://www.youtube.com/embed/youtubeID?rel=0">
</iframe>
</div>
</div>
You can make a fake audio player to toggle the Youtube iframe through Youtube Iframe API,
and also use the API to get informations that you want to display on your audio player.
Here is my example.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="player.css">
<script src="https://www.youtube.com/iframe_api"></script>
<script src="player.js"></script>
<script>
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '360',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
</script>
</head>
<body>
<!--Youtube-->
<div id="player" style="display: none; visibility: hidden;"></div>
<!--Player-->
<div class="audio-player">
<div class="player-controls">
<div id="radioIcon"></div>
<button id="playAudio"></button>
<div id="seekObjContainer">
<div id="seekObj">
<div id="percentage"></div>
</div>
</div>
<p><small id="currentTime">00:00</small></p>
</div>
</div>
</body>
</html>
player.js
var player;
function onPlayerReady(event) {
document.getElementById(ui.play).addEventListener('click', togglePlay);
timeupdater = setInterval(initProgressBar, 100);
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
document.getElementById(ui.play).classList.remove('pause');
document.getElementById(ui.percentage).style.width = 0;
document.getElementById(ui.currentTime).innerHTML = '00:00';
player.seekTo(0, true);
}
}
let ui = {
play: 'playAudio',
audio: 'audio',
percentage: 'percentage',
seekObj: 'seekObj',
currentTime: 'currentTime'
};
function togglePlay() {
if (player.getPlayerState() === 1) {
player.pauseVideo();
document.getElementById(ui.play).classList.remove('pause');
} else {
player.playVideo();
document.getElementById(ui.play).classList.add('pause');
}
}
function calculatePercentPlayed() {
let percentage = (player.getCurrentTime() / player.getDuration()).toFixed(2) * 100;
document.getElementById(ui.percentage).style.width = `${percentage}%`;
}
function calculateCurrentValue(currentTime) {
const currentMinute = parseInt(currentTime / 60) % 60;
const currentSecondsLong = currentTime % 60;
const currentSeconds = currentSecondsLong.toFixed();
const currentTimeFormatted = `${currentMinute < 10 ? `0${currentMinute}` : currentMinute}:${
currentSeconds < 10 ? `0${currentSeconds}` : currentSeconds
}`;
return currentTimeFormatted;
}
function initProgressBar() {
const currentTime = calculateCurrentValue(player.getCurrentTime());
document.getElementById(ui.currentTime).innerHTML = currentTime;
document.getElementById(ui.seekObj).addEventListener('click', seek);
function seek(e) {
const percent = e.offsetX / this.offsetWidth;
player.seekTo(percent * player.getDuration());
}
calculatePercentPlayed();
}
player.css
* {
box-sizing: border-box;
}
body {
background-size: 6px 6px !important;
background-image: linear-gradient(-45deg, rgba(0, 0, 0, 0) 46%, coral 49%, coral 51%, rgba(0, 0, 0, 0) 55%);
background-color: white;
padding-top: 60px;
}
.audio-player {
width: 470px;
padding: 35px 20px;
margin: auto;
background-color: white;
border: 1px solid black;
}
.audio-player .player-controls {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
}
.audio-player #radioIcon {
width: 30px;
height: 30px;
background: url("https://img.icons8.com/ios/50/000000/microphone.png") no-repeat center;
background-size: contain;
}
.audio-player #playAudio {
-webkit-appearance: none;
outline: none;
cursor: pointer;
border: none;
width: 30px;
height: 30px;
background: url("https://img.icons8.com/play") no-repeat center;
background-size: contain;
}
.audio-player #playAudio.pause {
background: url("https://img.icons8.com/pause") no-repeat center;
background-size: contain;
}
.audio-player p {
margin: 0 0 0 5px;
line-height: 1;
display: inline-flex;
}
.audio-player p small {
font-size: 10px;
}
.audio-player #seekObjContainer {
position: relative;
width: 300px;
margin: 0 5px;
height: 5px;
}
.audio-player #seekObjContainer #seekObj {
position: relative;
width: 100%;
height: 100%;
background-color: #e3e3e3;
border: 1px solid black;
}
.audio-player #seekObjContainer #seekObj #percentage {
position: absolute;
left: 0;
top: 0;
height: 100%;
background-color: coral;
}
The audio player came from here.
Hope this could help you guys!!
VIDEO_ID with actual ID of your YouTube video.
<div data-video="VIDEO_ID"
data-autoplay="0"
data-loop="1"
id="youtube-audio">
</div>
<script src="https://www.youtube.com/iframe_api"></script>
<script src="https://cdn.rawgit.com/labnol/files/master/yt.js"></script>
The answer is simple:
Use a 3rd party product like jwplayer or similar,
then set it to the minimal player size which is the audio player size (only shows player controls).
Voila.
Been using this for over 8 years.
I agree with Tom van der Woerdt. You could use CSS to hide the video (visibility:hidden or overflow:hidden in a div wrapper constrained by height), but that may violate Youtube's policies. Additionally, how could you control the audio (pause, stop, volume, etc.)?
You could instead turn to resources such as http://www.houndbite.com/ to manage audio.
Adding to the mentions of jwplayer and possible TOS violations, I would like to to link to the following repository on github: YouTube Audio Player Generation Library, that allows to generate the following output:
Library has the support for the playlists and PHP autorendering given the video URL and the configuration options.
var vid = "bpt84ceWAY0",
audio_streams = {},
audio_tag = document.getElementById('youtube');
fetch("https://"+vid+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=https%3A%2F%2Fwww.youtube.com%2Fget_video_info%3Fvideo_id%3D" + vid).then(response => {
if (response.ok) {
response.text().then(data => {
var data = parse_str(data),
streams = (data.url_encoded_fmt_stream_map + ',' + data.adaptive_fmts).split(',');
streams.forEach(function(s, n) {
var stream = parse_str(s),
itag = stream.itag * 1,
quality = false;
console.log(stream);
switch (itag) {
case 139:
quality = "48kbps";
break;
case 140:
quality = "128kbps";
break;
case 141:
quality = "256kbps";
break;
}
if (quality) audio_streams[quality] = stream.url;
});
console.log(audio_streams);
audio_tag.src = audio_streams['128kbps'];
audio_tag.play();
})
}
});
function parse_str(str) {
return str.split('&').reduce(function(params, param) {
var paramSplit = param.split('=').map(function(value) {
return decodeURIComponent(value.replace('+', ' '));
});
params[paramSplit[0]] = paramSplit[1];
return params;
}, {});
}
<audio id="youtube" autoplay controls loop></audio>
As an alternative answer, you can set the video's brightness to zero and the video area will go all black while the controls remain visible...
Via CSS...
filter: brightness(0%);
Via JS...
V.style.filter='brightness(0%)';
NB: Normal default value for brightness is 100%.
// YouTube video ID
var videoID = "CMNry4PE93Y";
// Fetch video info (using a proxy to avoid CORS errors)
fetch('https://cors-anywhere.herokuapp.com/' + "https://www.youtube.com/get_video_info?video_id=" + videoID).then(response => {
if (response.ok) {
response.text().then(ytData => {
// parse response to find audio info
var ytData = parse_str(ytData);
var getAdaptiveFormats = JSON.parse(ytData.player_response).streamingData.adaptiveFormats;
var findAudioInfo = getAdaptiveFormats.findIndex(obj => obj.audioQuality);
// get the URL for the audio file
var audioURL = getAdaptiveFormats[findAudioInfo].url;
// update the <audio> element src
var youtubeAudio = document.getElementById('youtube');
youtubeAudio.src = audioURL;
});
}
});
function parse_str(str) {
return str.split('&').reduce(function(params, param) {
var paramSplit = param.split('=').map(function(value) {
return decodeURIComponent(value.replace('+', ' '));
});
params[paramSplit[0]] = paramSplit[1];
return params;
}, {});
}
<audio id="youtube" controls></audio>

Categories

Resources