I would like to know how to speed up a youtube video 2x without the user clicking on the HTML5 (of the video), but instead by modifying the URL.
For example, I know how to watch video starting at a specific time by appending to the URL the parameter &t=1m1s (for 1 minute and one second). Is it possible to use a similar method to speed up the video 2x?
What parameters should I add to the URL to watch video in double speed (I'm using html5)?
There's no way to change playback speed by URL arguments.
Anyway, if you're working with HTML, you can take advantage of the YouTube Player iFrame API.
Here's how to configure your player with all the JavaScript:
https://developers.google.com/youtube/iframe_api_reference#Getting_Started
And here's the function you're looking for to set playback speed:
https://developers.google.com/youtube/iframe_api_reference#Playback_rate
So you can edit your onPlayerReady function like this:
function onPlayerReady(event) {
player.setPlaybackRate(2); // This is what you're looking for
event.target.playVideo();
}
You can of course pass on step 5 of the documentation as this will stop your video from playing after six seconds.
If you have trouble setting that up, I'll edit a JSFiddle later (couldn't do it at work as my Flash plugin won't launch).
Update :
Here's the JSFiddle working fine with this code exactly:
http://jsfiddle.net/jpreynat/e11oy0eu/
I was trying to do this exact same thing earlier this week.
A solution purely from a URL parameter isn't possible. (or if it is,
it's not documentation here:
https://developers.google.com/youtube/player_parameters)
I came accros this JSFiddle by Johan Preynat: http://jsfiddle.net/jpreynat/e11oy0eu/
Worked for me, so hopefully it'll be useful for you too
HTML
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
JavaScript
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
player.setPlaybackRate(2);
event.target.playVideo();
}
See also the YouTube documentation on this:
https://developers.google.com/youtube/iframe_api_reference
Can you inject a shift > or < from users input via url or easier javascript? Maybe its easier to force the hot key press from the users end.
Related
Using the standard gamePad code, not finding sound files even though the path name is correct?
I have definitely researched this question. For sure, I have found code on SO claiming to solve this dilemma, but this published code doesn't.
I am successfully finding the sound file using Preview under BBEdit's "Markup" Menu. But, the oh-oh surfaces when running my game on my commercial Server.
I am even successful when using keypress code is activated -- local on my Mac and on the Server.
The failure is when I am using the external Server to run my gamePad code to find the sound file when all my source code is loaded onto my Server. In this case, the sound does not play.
FILE HIERARCHY
games folder
Game_1 folder
game1.html
Game_Support folder
audio folder
js folder
HTML
<body onload="doBodyOnLoad()">
JS:
function doBodyOnLoad() {
$(document).ready(function() {
// ... //
}); // $(document).ready
} // doBodyOnload
function setupKeypresses() {
$(document).keydown(function(evt) {
let code = evt.keyCode || evt.which;
// for example:
if (code === "R")
{
movePaddleRight(); // this will call ouch() below
}
});
} // setupKeypresses
function PlaySound(id, src) {
let theSound = new Audio();
theSound.src = src;
theSound.play();
} // PlaySound
function ouch() {
updateScore(--thisScore);
// even the absolute path doesn't work ?
// var theSnd = "http://lovesongforever.com/games/Game_1/Game_1_Support/audio/explosion.mp3";
var theSnd = "Game_1_Support/audio/explosion.mp3";
PlaySound("audioPlaceHolder", theSnd);
// fade either the whole Board (okay), or just the Paddle (not! so much)
doFade("#gameBoard"); // doFade("#gameBoard > #gamePaddle") [not ready for Prime Time]
} // ouch
Thanks bunches for your patience with me!
This is because you're trying to autoplay an Audio element without user interaction to initiate the audio.
Firefox expresses a blocked play() call to JavaScript by rejecting the promise returned by HTMLMediaElement.play() with a NotAllowedError. All major browsers which block autoplay express a blocked play via this mechanism. In general, the advice for web authors when calling HTMLMediaElement.play(), is to not assume that calls to play() will always succeed, and to always handle the promise returned by play() being rejected.
https://hacks.mozilla.org/2019/02/firefox-66-to-block-automatically-playing-audible-video-and-audio/
I think it will work if you click or tap on the page first. Gamepad button presses may work for this too depending on the implementation.
I am building a web page with a list of video records. Clicking on each video record opens a modal dialog on the same page with detail of the record and an HTML5 Video player.
A user can open one video, close it, and open another as many times as they want. However, on Chome specifically, after 3-5 videos, the browser starts hanging for upwards of two minutes while displaying a message "waiting for socket".
Doing some reading, I have narrowed it to Chrome's inability to open more than 6 connections to the same host.
I must be doing something wrong with how I dispose of the Media players. I believe the socket remains open to the media for some period even though the html for the player has been removed from the dom.
Using:
Bootstrap,
MediaElement.js,
HTML5 Video,
MVC,
Controller returning "Range Request" of FilePathResult
// Handling Bootstrap Modal Window Close Event
// Trigger player destroy
$("#xr-interaction-detail-modal").on("hidden.bs.modal", function () {
var player = xr.ui.mediaelement.xrPlayer();
if (player) {
player.pause();
player.remove();
}
});
I am going to go for my Self Learner badge, here, and answer my own question.
I did about 8 hours of research on this and came up with a great solution. Three things had to be done.
Set the HTML5 video src to something other than the original URL. This will trigger the player to close the open socket connection.
Set the HTML5 video src to a Base64 encoded data object. This will prevent the Error Code 4 issue MEDIA_ERR_SRC_NOT_SUPPORTED.
For issues in older versions of Firefox, also trigger the .load() event.
My Code:
// Handling Bootstrap Modal Window Close Event
// Trigger player destroy
$("#xr-interaction-detail-modal").on("hidden.bs.modal", function () {
var player = xr.ui.mediaelement.xrPlayer();
if (player) {
player.pause();
("video,audio").attr("src","data:video/mp4;base64,AAAAHG...MTAw");
player.load();
player.remove();
}
});
I came up with the idea to load the data object as the src. However, I'd like to thank kud on GitHub for the super small base64 video.
https://github.com/kud/blank-video
Added a line between pause() and remove():
// Handling Bootstrap Modal Window Close Event
// Trigger player destroy
$("#xr-interaction-detail-modal").on("hidden.bs.modal", function () {
var player = xr.ui.mediaelement.xrPlayer();
if (player) {
player.pause();
("video,audio").attr("src", "");
player.remove();
}
});
A notable issue that's appearing as I'm building a simple audio streaming element in HTML5 is that the <audio> tag doesn't behave as one would expect in regards to playing and pausing a live audio stream.
I'm using the most basic HTML5 code for streaming the audio, an <audio> tag with controls, the source of which is a live stream.
Current outcome: When the stream is first played, it plays whatever is streaming as expected. When it's paused and played again, however, the audio resumes exactly where it left off when the stream was previously paused. The user is now listening to a delayed version of the stream. This occurrence isn't browser-specific.
Desired outcome: When the stream is paused, I want the stream to stop. When it is played again, I want it resume where the stream is currently at, not where it was when the user paused the stream.
Does anyone know of a way to make this audio stream resume properly after it's been paused?
Some failed attempts I've made to fix this issue:
Altering the currentTime of the audio element does nothing to streaming audio.
I've removed the audio element from the DOM when the user stops stream playback and added it back in when user resumes playback. The stream still continues where the user left off and worse yet downloads another copy of the stream behind the scenes.
I've added a random GET variable to the end of the stream URL every time the stream is played in an attempt to fool the browser into believing that it's playing a new stream. Playback still resumes where the user paused the stream.
Best way to stop a stream, and then start it again seems to be removing the source and then calling load:
var sourceElement = document.querySelector("source");
var originalSourceUrl = sourceElement.getAttribute("src");
var audioElement = document.querySelector("audio");
function pause() {
sourceElement.setAttribute("src", "");
audioElement.pause();
// settimeout, otherwise pause event is not raised normally
setTimeout(function () {
audioElement.load(); // This stops the stream from downloading
});
}
function play() {
if (!sourceElement.getAttribute("src")) {
sourceElement.setAttribute("src", originalSourceUrl);
audioElement.load(); // This restarts the stream download
}
audioElement.play();
}
Resetting the audio source and calling the load() method seems to be the simplest solution when you want to stop downloading from the stream.
Since it's a stream, the browser will stop downloading only when the user gets offline. Resetting is necessary to protect your users from burning through their cellular data or to avoid serving outdated content that the browser downloaded when they paused the audio.
Keep in mind though that when the source attribute is set to an empty string, like so audio.src = "", the audio source will instead be set to the page's hostname. If you use a random word, that word will be appended as a path.
So as seen below, setting audio.src ="", means that audio.src === "https://stacksnippets.net/js". Setting audio.src="meow" will make the source be audio.src === "https://stacksnippets.net/js/meow" instead. Thus the 3d paragraph is not visible.
const audio1 = document.getElementById('audio1');
const audio2 = document.getElementById('audio2');
document.getElementById('p1').innerHTML = `First audio source: ${audio1.src}`;
document.getElementById('p2').innerHTML = `Second audio source: ${audio2.src}`;
if (audio1.src === "") {
document.getElementById('p3').innerHTML = "You can see me because the audio source is set to an empty string";
}
<audio id="audio1" src=""></audio>
<audio id="audio2" src="meow"></audio>
<p id="p1"></p>
<p id="p2"></p>
<p id="p3"></p>
Be aware of that behavior if you do rely on the audio's source at a given moment. Using the about URI scheme seems to trick it into behaving in a more reliable way. So using "about:" or "about:about", "about:blank", etc. will work fine.
const resetAudioSource = "about:"
const audio = document.getElementById('audio');
audio.src = resetAudioSource;
document.getElementById('p1').innerHTML = `Audio source: -- "${audio.src}"`;
// Somewhere else in your code...
if (audio.src === resetAudioSource){
document.getElementById('p2').innerHTML = "You can see me because you reset the audio source."
}
<audio id="audio"></audio>
<p id="p1"></p>
<p id="p2"></p>
Resetting the audio.src and calling the .load() method will make the audio to try to load the new source. The above comes in handy if you want to show a spinner component while the audio is loading, but don't want to also show that component when you reset your audio source.
A working example can be found here: https://jsfiddle.net/v2xuczrq/
If the source is reset using a random word, then you might end up with the loader showing up when you also pause the audio, or until the onError event handler catches it. https://jsfiddle.net/jcwvue0s/
UPDATE: The strings "javascript:;" and "javascript:void(0)" can be used instead of the "about:" URI and this seems to work even better as it will also stop the console warnings caused by "about:".
Note: I'm leaving this answer for the sake of posterity, since it was the best solution I or anyone could come up with at the time for my issue. But I've since marked Ciantic's later idea as the best solution because it actually stops the stream downloading and playback like I originally wanted. Consider that solution instead of this one.
One solution I came up with while troubleshooting this issue was to ignore the play and pause functions on the audio element entirely and just set the volume property of the audio element to 0 when user wishes to stop playback and then set the volume property back to 1 when the user wishes to resume playback.
The JavaScript code for such a function would look much like this if you're using jQuery (also demonstrated in this fiddle):
/*
* Play/Stop Live Audio Streams
* "audioElement" should be a jQuery object
*/
function streamPlayStop(audioElement) {
if (audioElement[0].paused) {
audioElement[0].play();
} else if (!audioElement[0].volume) {
audioElement[0].volume = 1;
} else {
audioElement[0].volume = 0;
}
}
I should caution that even though this achieves the desired functionality for stopping and resuming live audio streams, it isn't ideal because the stream, when stopped, is actually still playing and being downloaded in the background, using up bandwidth in the process.
However, this solution doesn't necessarily take up more bandwidth than just using .play() and .pause() on a streaming audio element. Simply using the audio tag with streaming audio uses up a great deal of bandwidth anyway, because once streaming audio is played, it continues to download the contents of the stream in the background when it is paused.
It should be noted that this method won't work in iOS because of purposefully built-in limitations for iPhones and iPads:
On iOS devices, the audio level is always under the user’s physical control. The volume property is not settable in JavaScript. Reading the volume property always returns 1.
If you choose to use the workaround in this answer, you'll need to create a fallback for iOS devices that uses the play() and pause() functions normally, or your interface will be unable to pause the stream.
Tested #Ciantics code and it worked with some modifications, if you want to use multiple sources.
As the source is getting removed, the HTML audio player becomes inactive, so the source (URL) needs to be added directly after again to become active.
Also added an event listener at the end to connect the function when pausing:
var audioElement = document.querySelector("audio");
var sources = document.querySelector("audio").children;
var sourceList = [];
for(i=0;i<sources.length;i++){
sourceList[i] = sources[i].getAttribute("src");
}
function pause() {
for(i=0;i<sources.length;i++){
sources[i].setAttribute("src", "");
}
audioElement.pause();
// settimeout, otherwise pause event is not raised normally
setTimeout(function () {
audioElement.load(); // This stops the stream from downloading
});
for(i=0;i<sources.length;i++){
if (!sources[i].getAttribute("src")) {
sources[i].setAttribute("src", sourceList[i]);
audioElement.load(); // This restarts the stream download
}
}
}
audioElement.addEventListener("pause", pause);
I am wondering how I make get an audio file to play 'continuously' on all pages. So if the audio file has played for 20 seconds, then when navigating on another page it will continue from where it left off. I also am trying to get the volume to decrease after navigating away from my home page. Any tips or advice would me appreciated! Thanks =D
<audio src="songforsite.mp3" loop="true" autoplay="true" controls>
Unsupported in Firefox
</audio>
Yes, it is possible. try this:
<audio preload="auto" src="a.mp3" loop="true" autobuffer>
Unsupported in Firefox
</audio>
<script>
function setCookie(c_name,value,exdays)
{
var exdate=new Date();
exdate.setDate(exdate.getDate() + exdays);
var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
document.cookie=c_name + "=" + c_value;
}
function getCookie(c_name)
{
var i,x,y,ARRcookies=document.cookie.split(";");
for (i=0;i<ARRcookies.length;i++)
{
x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
x=x.replace(/^\s+|\s+$/g,"");
if (x==c_name)
{
return unescape(y);
}
}
}
var song = document.getElementsByTagName('audio')[0];
var played = false;
var tillPlayed = getCookie('timePlayed');
function update()
{
if(!played){
if(tillPlayed){
song.currentTime = tillPlayed;
song.play();
played = true;
}
else {
song.play();
played = true;
}
}
else {
setCookie('timePlayed', song.currentTime);
}
}
setInterval(update,1000);
</script>
If you really navigate to another page, then you will not get really continuous playback.
There are three common approaches:
open your audio player in a popup
frames: one main frame for your page to display in, a small frame for the audio player
not really navigating to other pages, but do everything with AJAX and thereby not actually reloading the page, but only changing parts of the document structure dynamically; maybe adding real link functionality including changing the address bar by using the HTML5 History API
All approaches have their pros/cons. Popup is maybe the easiest to implement, and has the least drawbacks (compared to frames).
I also am trying to get the volume to decrease after navigating away from my home page.
Then catch any clicks on your “home” link/button, and call the volume method of the audio element with a parameter value ranging from 0 to 1 to set the volume.
well .. a clean and neat way to do it , is the way that soundcloud.com and spoify.com made through ajaxifing all the pages
fix a page and change the pages content through ajax ,and change the url as well to give the user the illusion of navigating
this is not the easiest or fastest solution ,but it's the cleanest one ..far away from the fear of browsers incompatibilities
Here is my scenario:
I am building a "kiosk" application in safari with 2 videos, one acting as a "screensaver" and the other is a supplementary video. The SS is looping fine via: (done on body onload="init()")
var myVideo = document.getElementById('screensaver');
myVideo.addEventListener('ended', playVideo, false);
function playVideo(){
var myVideo = document.getElementById('screensaver');
myVideo.play();
}
When the user taps the screen during the SS, it fades out $('#screensaver').fadeOut(1000); and the user is presented a question with a button to play the next video.
When the second video is done via:
$('#presentation').bind('ended', function(){
$(this).fadeOut(1000, function(){
$('#swapVideo').show(); //Overlay for user interaction
$('#screensaver').fadeIn(1000);
$('#screensaver').get(0).play();
});
});
The SS shows up, plays, but no longer loops. Are eventListeners lost when the display is set to none?
The same thing happens when I try to play the second video again. The 'ended' eventListener seems to be lost...
I believe that iOS ignores .play(). Apple believes it's best to prevent sites from automatically playing content, which could potentially eat up someone's data plan or create undesirable actions on iOS.
On iOS, .play() can only executed directly from a user interaction.
Documentation
As for your question, event listeners are not unbound if you change the display property.
Fiddle
$('.container').on('custom', function (evt) {
$(this).toggle();
});