0

Using iOS 9.3, link conditioning set to 3g speed, loading a video in the youtube iframe api in safari.

I would expect the iframe api to realize that it has been buffering a bunch and try to get a lower quality stream to keep the video playback smooth, like it does in the native youtube app.

Am I missing something obvious? I basically copied and pasted out of the youtube ios helper wrapper but it still tries to play in a quality that is too high for the connection speed.

<!DOCTYPE html>
<html>
<head>
    <style>
    body { margin: 0; width:100%; height:100%;  background-color:#000000; }
    html { width:100%; height:100%; background-color:#000000; }

    .embed-container iframe,
    .embed-container object,
    .embed-container embed {
        position: absolute;
        top: 0;
        left: 0;
        width: 100% !important;
        height: 100% !important;
    }
    </style>
</head>
<body>
    <div class="embed-container">
        <div id="player"></div>
    </div>
    <script src="https://www.youtube.com/iframe_api" onerror="window.location.href='ytplayer://onYouTubeIframeAPIFailedToLoad'"></script>
    <script>
    var player;
    var error = false;

    YT.ready(function() {
        player = new YT.Player('player', {
  "events" : {
    "onPlaybackQualityChange" : "onPlaybackQualityChange",
    "onReady" : "onReady",
    "onError" : "onPlayerError",
    "onStateChange" : "onStateChange"
  },
  "width" : "100%",
  "height" : "100%",
  "videoId" : 'NP7nK2zPirc',
  "playerVars" : {
    "showinfo" : 0,
    "modestbranding" : 1,
    "autohide" : 1,
    "playsinline" : 1,
    "controls" : 0
  }
});
        player.setSize(window.innerWidth, window.innerHeight);
        window.location.href = 'ytplayer://onYouTubeIframeAPIReady';

        // this will transmit playTime frequently while playng
        function getCurrentTime() {
             var state = player.getPlayerState();
             if (state == YT.PlayerState.PLAYING) {
                 time = player.getCurrentTime()
                 // window.location.href = 'ytplayer://onPlayTime?data=' + time;
             }
        }

        window.setInterval(getCurrentTime, 500);

    });

    function onReady(event) {
        // window.location.href = 'ytplayer://onReady?data=' + event.data;
    }

    function onStateChange(event) {
        if (!error) {            
            // window.location.href = 'ytplayer://onStateChange?data=' + event.data;
        }
        else {
            error = false;
        }
    }

    function onPlaybackQualityChange(event) {
        // window.location.href = 'ytplayer://onPlaybackQualityChange?data=' + event.data;
    }

    function onPlayerError(event) {
        if (event.data == 100) {
            error = true;
        }
        // window.location.href = 'ytplayer://onError?data=' + event.data;
    }

    window.onresize = function() {
        player.setSize(window.innerWidth, window.innerHeight);
    }
    </script>
</body>
</html>
raphael
  • 447
  • 4
  • 17

1 Answers1

0

Based from this documentation, if the playback quality changes, the onPlaybackQualityChange event will fire, and your code should respond to the event rather than the fact that it called the setPlaybackQuality function.

onPlaybackQualityChange event fires whenever the video playback quality changes. For example, if you call the setPlaybackQuality(suggestedQuality) function, this event will fire if the playback quality actually changes. Your application should respond to the event and should not assume that the quality will automatically change when the setPlaybackQuality(suggestedQuality) function is called. Similarly, your code should not assume that playback quality will only change as a result of an explicit call to setPlaybackQuality or any other function that allows you to set a suggested playback quality.

Then I recommend calling the getAvailableQualityLevels() function to determine which quality levels are available for a video. For example, if your page displays a 1280px by 720px video player, a hd720 quality video will actually look better than an hd1080 quality video.

Check these related SO threads:

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');
    }
}

Hope this helps!

Community
  • 1
  • 1
abielita
  • 13,147
  • 2
  • 17
  • 59