I need to implement a video playback speed controller (e.g.: play the video at 1/2 speed) for youtube videos, and I'm thinking that HTML5 is currently the only way to do this (if it's even possible). I know very little about HTML5 video, but I know a lot about the youtube js API. Can anyone point me in the right direction? It's okay if the solution will only work in some browsers.
The new iframe api allows you to control the speed of the video:
iframe api reference: Setting the playback rate
The default playback rate is 1, which indicates that the video is playing at normal speed. Playback rates may include values like 0.25, 0.5, 1, 1.5, and 2.
Also:
Calling this function does not guarantee that the playback rate will actually change.
Example code:
function onYouTubeIframeAPIReady() {
var player;
player = new YT.Player('player', {
videoId: 'M7lc1UVf-VE',
playerVars: { 'autoplay': 1, 'controls': 0 },
events: {
'onReady': function(e){
// e.target = player
e.target.setPlaybackRate(0.5); // set to half speed
e.target.playVideo(); // watch lolcats in slow motion :)
},
}
});
}
http://mediaelementjs.com/ is crossbrowser,uses flash or html5 depending on the browser support and has all the methods you are looking for.
$('#video').playbackRate = 3.0 or
$('video').playbackRate = 3.0 depending on version
Related
I use React to set iframe with youtube video on page in correct size. All works well but for mobiles doesn't work autoplay option.
What is interesting for page, what I have as example video it works perfect.
<iframe type="text/html" allowTransparency="true" height="100%" width="100%" preload="metadata" gesture="media" allow="encrypted-media" className="autoplay-iframe"
src={`https://www.youtube.com/embed/`+this.props.autoplay+`?autoplay=1&version=3&html5=1&hd=1&controls=0&loop=1&playlist=`+this.props.autoplay+`&playsinline=1&rel=0&showinfo=0&modestbranding=1&related=0&enablejsapi=1&origin=`+window.location.hostname} frameborder="0"></iframe>
above is my iframe code.
I cut some part of iframe code but there are just style in styles attribute. It isn't important for autoplay.
The same finally url for other page works. I'm not sure why. Any hints how I can solve this problem?
Thanks in advance.
You will not be able to implement this, since it is intentionally disabled to all mobile devices. The reason is for the user to save cellular data. It is also cited in this post.
The reason that video autoplay doesn’t work is simple. The feature is
deliberately disabled in both iOS and Android for mobile devices.
The reason this is done is to save mobile users money. Such devices
(especially mobile phones) often use data connections that charge by
bandwidth. They have data limits and going over results in a fee.
This statement was also supported with the following SO post.
no autoplay in iframe HTML5 player on mobile (Android Chrome and Firefox)?
how to get embedded youtube video to autostart on iphone
Youtube autoplay not working on mobile devices with embedded HTML5 player
I was able to get Youtube videos to play (without muting them). Because loading Youtube videos inline was upsetting Google and their new Core Web Vitals, we implemented a thumbnail placeholder that when clicked (jQuery) initiates loading the video using the Youtube Iframe API. I too could not get them to autoplay at first. The issue was resolved by having the API embed the Iframe--not putting the iframe in place before hand. It autoplays on iOS Safari, Chrome and Firefox. Here's what worked for me:
On document ready:
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function onYouTubeIframeAPIReady(yt_id, iframe_id, iframe_width, iframe_height){
player = new YT.Player(iframe_id, {
width: iframe_width,
height: iframe_height,
videoId: yt_id,
playerVars: { 'autoplay': 1, 'playsinline': 1 },
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
//event.target.mute();
event.target.setVolume(70);
event.target.playVideo();
}
on click event:
$('.yt_video_link').on('click', function(e) {
e.preventDefault();
var div_id = $(this).attr('id');
var div_iframe = div_id + '_iframe';
var yt_id = $('#' + div_id).data('ytid');
$('#' + div_id + ' .yt_video_play').css('display', 'none');
onYouTubeIframeAPIReady(yt_id, div_iframe, 560, 315);
});
HTML:
<div id='yt_video_desktop' class='yt_video_link mobile_hide' data-ytid='<?=$yt_id?>'>
<div id='yt_video_desktop_player' class='yt_video'>
<img src='/catalog/images/yt_video_thumb_<?=$yt_id?>.jpg' alt='play desktop video' width='768' height='432' id='yt_video_desktop_iframe'>
</div>
<div class='yt_video_play'></div>
</div>
Google official statement "Due to this restriction, functions and parameters such as autoplay, playVideo(), loadVideoById() won't work in all mobile environments.
Reference: https://developers.google.com/youtube/iframe_api_reference
By adding the parameter playsinline: 1 I managed to make the autoplay work on android and ios.
createYoutubePlayer() {
this.youtubePlayer = new YT.Player('youtubePlayer', {
videoId: 'YOURID', // YouTube Video ID
width: 277, // Player width (in px)
height: 600, // Player height (in px)
playerVars: {
autoplay: 1, // Auto-play the video on load
controls: 0, // Show pause/play buttons in player
showinfo: 1, // Hide the video title
modestbranding: 1, // Hide the Youtube Logo
loop: 1, // Run the video in a loop
fs: 0, // Hide the full screen button
cc_load_policy: 0, // Hide closed captions
iv_load_policy: 3, // Hide the Video Annotations
autohide: 1, // Hide video controls when playing
playsinline: 1, //forbid fullscreen on ios
},
events: {
onReady: (e) => {
e.target.mute();
},
onStateChange: (e) => {this.onPlayerStateChange(e)}
}
});
}
The rules have changed so most new mobiles will now let you autoplay, but most video streaming sites like youtube and vimeo haven't enabled the functionality yet. The reason the html5 video worked but the iframe didn't is because youtube disabled it.
For anyone dealing with this on react native, you can override the user agent and it works like a charm:
<WebView
userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
...
The reason that video autoplay doesn't work is simple. The feature is deliberately disabled in both iOS and Android for mobile devices. The reason this is done is to save mobile users money. Such devices (especially mobile phones) often use data connections that charge by bandwidth.
I am writing a simple Chrome extension to change the speed of a video on youtube. The code can be found here.
In essence, I am using the following code to change the speed:
document.getElementsByTagName("video")[0].playbackRate = 2;
This works well, but doesn't affect the settings on the player. Which also cause some issues, especially when you switch videos.
Is there a better approach to interact directly with the player?
You may try Youtube Player API iframe embeds, Iframe API allows you to control the speed of the video.
The default playback rate is 1, which indicates that the video is playing at normal speed. Playback rates may include values like 0.25, 0.5, 1, 1.5, and 2.
Here is a sample code for Iframe API:
function onYouTubeIframeAPIReady() {
var player;
player = new YT.Player('player', {
videoId: 'M7lc1UVf-VE',
playerVars: { 'autoplay': 1, 'controls': 0 },
events: {
'onReady': function(e){
// e.target = player
e.target.setPlaybackRate(0.5); // set to half speed
e.target.playVideo(); // watch lolcats in slow motion :)
},
}
});
}
So I hide my embed youtube video controls:
var player = new YT.Player('player', {
playerVars: {
controls: 0,
showinfo: 0,
modestbranding: 1,
autohide: 1,
iv_load_policy: 3,
rel: 0
}
});
But I still can open make the video full screen by double-clicking the video, which is fine.
Actually, I'd also like to have a custom button to make the player full screen.
I could actually make the iframe#player full screen, or use one of these strategies but I'd much rather have a native way to do it, which means actually calling the method that is called on a double click on the video.
Any chance I can do that? The doc doesn't seem to talk about it explicitly, and inspecting the player JS var did not give me much success either.
I would like to make a Chrome extension that is able to control the Netflix player.
The current Netflix player is written in HTML5 as far as I can tell, so I was wondering if there is a way to control the player, e.g. play, pause, volume control and changing the position of the video.
I've tried using this to control the playing and pausing functions and it works.
document.getElementsByClassName("player-control-button player-play-pause")[0].click();
I've also tried using but then I just get an error saying that videoPlayer() isn't a function
netflix.cadmium.objects.videoPlayer();
Is there something similar I can do to change the volume and the position of the video?
Thanks!
First get the <video> element as variable e.g. by:
media = document.getElementById("netflixVideoPlayer");
After that you can control the volume.
To mute the sound:
media.volume = 0
Turn the volume to 100%:
media.volume = 1
Turn the volume to 60%:
media.volume = 0.6
Start the video:
media.start();
Pause the video:
media.pause();
The YouTube API docs define the minimum size of an embedded player t to be 200px by 200px (link).
To allow room for critical player functionality, players must be at least 200px by 200px.
My testing has lead me to the conclusion that this is true. If I try to play a video in a player which is smaller than the minimum size, I get an error message which says "Video player is too small." and the video will not play.
However, smaller players are possible. SwitchCam, for example, uses them on pages like this one.
I've tried reducing the player size by setting it's height and width attributes, by using it's style attribute and by wrapping it in a containing element which has it's height and width set. None of these options appear to work.
What else can I try to reduce the size of the player?
EDIT
It appears that some videos will play in really small players but others will not. If you're going to test a potential solution, please use this video ID: -rMTExNTx2s
It's appears there is a restriction on some video which don't allow embeding video on size inferior to 200*200 (px). This restriction is not applied for all video (maybe older than last update youtube API, i don't know).
After some tests, this restriction is applied when youtube player readystate changed to status: PlayerState.PLAYING (evt.data === 1)
So as a basic workaround, you could change size of iframe 'on the fly' after the satus has been updated, see demo&code below:
DEMO
var player,
myWidth = "114px",
myHeight = "65px";
function onYouTubePlayerAPIReady() {
player = new YT.Player('testVideo', {
height: myWidth,
width: myHeight,
videoId: '-rMTExNTx2s',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
},
playerVars: {
controls:0,
showinfo:0
}
});
}
function onPlayerStateChange(evt) {
if (evt.data == -1) {
evt.target.a.width = "200px";
evt.target.a.height = "200px";
}
else if (evt.data == 1) {
evt.target.a.className = "";
evt.target.a.width = myWidth;
evt.target.a.height = myHeight;
done = true;
}
}
As you can ssee in this DEMO, i set an hidden class with css .hidden{opacity:0}. This is used to hide player before the video is loaded. Using display:none; doesn't work, its surely an other API restriction.
Still in this DEMO, you have to wait until the video has started to play to see the player appears.
You have now to find the best workaround which could fit your needs, using e.g a thumbnail image and moving from negative offset player to wished location when readystate has changed, hope you got the idea.
Not the most elegant solution, but have you thought about actually scaling down a larger player with the CSS3 transform: scale() property? Beware it's not supported in IE < 9.
The main reason not to do this, though, is that you'll be reducing the size of the UI controls which in turn reduces usability.