Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

YouTube iFrame API "setPlaybackQuality" or "suggestedQuality" not working

I'm having some trouble setting the quality settings on a video via the Youtube iFrame API. This is my code:

var player;

player = new YT.Player('player', {
    height: '490',
    width: '725',
    videoId: yturl,
    /* setPlaybackQuality: 'hd720', <-- DOES NOT WORK */
    /* suggestedQuality: 'hd720',   <-- DOES NOT WORK */
    events: {
        'onReady': onPlayerReady
    }
});

function onPlayerReady(event) {
    player.setPlaybackQuality('hd720');       // <-- DOES NOT WORK
    event.target.setPlaybackQuality('hd720'); // <-- DOES NOT WORK
    player.setVolume(100);                    // <-- DOES WORK
    console.log(player.getPlaybackQuality()); // <-- Prints 'small' to console
    event.target.playVideo();
}

The funny thing is that my call to player.setPlaybackQuality or event.target.setPlaybackQuality doesn't give any errors. It just looks as if the player ignores it. A call to, say, player.setSuggestedQuality (a function that doesn't exist) throws an error as expected.

I've tried all the valid string parameters as outlined in the API reference ('medium', 'large', 'hd720' etc). None of them work.

Anyone have any suggestions to how I'm supposed to set this property?

like image 557
o01 Avatar asked Jan 10 '12 11:01

o01


People also ask

Can you play videos with YouTube API?

The IFrame player API lets you embed a YouTube video player on your website and control the player using JavaScript. Using the API's JavaScript functions, you can queue videos for playback; play, pause, or stop those videos; adjust the player volume; or retrieve information about the video being played.

How do I unmute an iFrame video?

Until and unless you have allow="autoplay;" in your iframe tag you wont be able to unmute the video. Add this attribute and further unMute function will work. Show activity on this post. Usually, you can just click the mute button to unmute it.

What is API iFrame?

Overview. Developers can use the iFrame API to programmatically create and interact with an Embed or with multiple Embeds in the same web app. The iFrame API includes methods that you can use to start playback, change the content rendering in an Embed, or stop playback.


4 Answers

I have the exact same problem and workaround. I think what's happening is that YouTube is only allowing quality levels based on the actual size of the display, so unless you have your video 720px tall you can't default to 720p before it's actually playing. Then the user controls kick in and YouTube stops being a dick.


EDIT

Just hit a breakthrough: If you use event 3 (buffering) instead of event 5 (playing) there's no stutter for the user. Quality is changed as soon as it starts loading. Only weird thing is you need to set it in onPlayerReady as well or it doesn't work.

function onPlayerReady(event) {
    event.target.setPlaybackQuality('hd720');
}
function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.BUFFERING) {
        event.target.setPlaybackQuality('hd720');
    }
}
like image 116
Jedka Avatar answered Sep 30 '22 22:09

Jedka


Found a possible hack/solution.

If I wait until the video has started playing, then apply setPlaybackQuality - it works. Thusly:

player = new YT.Player('player', {
    height: '490',
    width: '725',
    videoId: yturl,
    events: {
        'onReady': onPlayerReady,
        'onStateChange': onPlayerStateChange
    }
});

function onPlayerReady(event) {
    player.setVolume(100);
    event.target.playVideo();
}

function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.PLAYING) {
        event.target.setPlaybackQuality('hd720');  // <-- WORKS!
    }
}

However, the solution isn't ideal as the video first starts to buffer on a lower quality - then switch to 720 once it starts playing. Any comments or alternative solutions will be appreciated.

like image 38
o01 Avatar answered Sep 30 '22 22:09

o01


Problem is YouTube selects the most appropriate playback quality, so it overrides setPlaybackQuality() in the onPlayerReady() function.

I've found a solution to force YouTube's player to play in any quality you desire no matter the width and height of the player:

var player;
function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
        height: '180',
        width: '320',
        videoId: 'M7lc1UVf-VE',
        events: {
        'onReady': onPlayerReady,
        'onPlaybackQualityChange': onPlayerPlaybackQualityChange,
        'onStateChange': onPlayerStateChange
        }
    });
}


function onPlayerReady(event) {
    event.target.playVideo();
}

function onPlayerPlaybackQualityChange(event) {
    var playbackQuality = event.target.getPlaybackQuality();
    var suggestedQuality = 'hd720';

    console.log("Quality changed to: " + playbackQuality );

    if( playbackQuality !== 'hd720') {
        console.log("Setting quality to " + suggestedQuality );
        event.target.setPlaybackQuality( suggestedQuality );
    }
}

The code ensures the quality change is the suggested.

Keep in mind: the user couldn't change the video quality with the player button with that code.

Anyway, you could force the suggested quality just once.

Tested in GChrome, Firefox, and Safari.

like image 42
jonalvarezz Avatar answered Oct 01 '22 00:10

jonalvarezz


i found a solution that works perfectly for me:

 function onPlayerStateChange(event) {
   //Some code...

   $(".btn-change-quality").on("click",  function(){
       pauseVideo();
       player.setPlaybackQuality('hd720');
       playVideo();
    });
} 
like image 31
user3164028 Avatar answered Sep 30 '22 23:09

user3164028