web-dev-qa-db-fra.com

Comment réparer "Si la lecture ne commence pas sous peu, essayez de redémarrer votre appareil" à l'aide de l'API Youtube iFrame sur iPad?

J'ai créé un petit script de streaming YouTube qui lit de manière aléatoire des vidéos de musique YouTube ou à partir d'une file d'attente. Cela a bien fonctionné pendant des mois, jusqu'à cette semaine, où il ne semble pas vouloir charger les vidéos avec un iPad/iPhone. Je reçois à la place l'erreur suivante:

Si la lecture ne commence pas sous peu, essayez de redémarrer votre appareil.

Ce que j'ai essayé:

J'ai essayé Safari, Chrome, Firefox et Opera et ils ont tous des erreurs. J'ai essayé d'effacer les données/cache du site Web, de redémarrer l'appareil, de le redémarrer complètement. Rien ne fonctionne. Ce qui est étrange, c’est que cela fonctionne parfaitement sur un bureau Windows, ce qui me porte à croire que ce n’est pas une erreur de code, mais quelque chose qui a changé avec l’API ou avec Safari. Mon code n'a pas été modifié récemment non plus, ce qui aurait pu l'empêcher de fonctionner.

J'ai essayé de le déboguer en utilisant jsconsole.com, rien de suspect n'apparaît. Dans certains cas, le lecteur se charge, le titre de la vidéo s’affiche, de même que l’image, mais au bout de 30 secondes environ, l’erreur ci-dessus s’affiche en même temps que le viseur de chargement.

Je suis conscient que playVideo (); ne fonctionne pas (lecture automatique) sur les appareils iOS. C'est bon, et encore une fois, le script a fonctionné auparavant, je n'ai eu qu'à appuyer sur play sur la vidéo first. Mais maintenant, il semble qu'iOS tente de lire automatiquement la vidéo. J'ai donc également testé en supprimant les appels à playVideo (), le problème persiste.

Testé sur iPad 2, iPad mini et iPhone 4 (tous avec la dernière iOS disponible sur l'appareil et tous fonctionnaient auparavant). 

Je suis désemparé et j'essaie de résoudre ce problème avant le week-end pour une fête à la maison :) J'apprécierais donc toute aide ou allusion quant à ce qui pourrait causer l'échec sur iOS.

Voici le code 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',
        events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
        }
    });
}

// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
    check_queue_timer = setTimeout(check_queue(),3000);
}

// 5. The API calls this function when the player's state changes.
//    The function indicates that when playing a video (state=1),
//    the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
    if (event.data === 0) {
        // TRACK AS DONE, REFRESH QUEUE AND GET NEXT SONG
        // POST TO WRITE TO FILE
        $.ajax({
            type: 'POST',
            url: site_url+'ajax_next_track',
            dataType: 'json',
            data: 'queue_id='+$('#queue_id').val(),
            cache: false,
            success:
            function(data){

                if(data.status == 'success'){
                    $("#queue_table").empty();
                    if(data.queue.length == 0){
                        check_queue_timer = setTimeout(check_queue(),3000);
                    }
                    $.each(data.queue, function(i, item) {
                        if(i == 0){
                            event.target.loadVideoById(item.video_id);
                            event.target.playVideo();
                            $('#queue_id').val(item.queue_id);
                        }
                        $('#queue_table').append('<tr><td>'+item.title+'</td></tr>');
                    });
                }
                else{
                    console(data.message);
                }
            },
            error:
            function( jqXHR, textStatus, errorThrown ){
                $('#error_msg').html('Something broke.').fadeIn();
            }

        });
    }
}
function stopVideo() {
    player.stopVideo();
}

function check_queue(){
    $.ajax({
        type: 'POST',
        url: site_url+'ajax_next_track',
        dataType: 'json',
        data: 'no_delete=1',
        cache: false,
        success:
        function(data){

            if(data.status == 'success'){
                $("#queue_table").empty();
                if(data.queue.length == 0){
                    clearTimeout(check_queue_timer);
                    check_queue_timer = setTimeout(check_queue(),3000);
                }
                $.each(data.queue, function(i, item) {
                    if(i == 0){
                        player.loadVideoById(item.video_id);
                        player.playVideo();
                        $('#queue_id').val(item.queue_id);
                        clearTimeout(check_queue_timer);
                    }
                    $('#queue_table').append('<tr><td>'+item.title+'</td></tr>');
                });
            }
            else{
                console(data.message);
            }
        },
        error:
        function( jqXHR, textStatus, errorThrown ){
            $('#error_msg').html('Something broke.').fadeIn();
        }

    });
}

UPDATE 1 (25 NOV 2015)

J'ai décidé de partir de zéro et de travailler avec l'exemple de code sur https://developers.google.com/youtube/iframe_api_reference . Il semble que loadVideoById () ne fonctionne plus sur les iPad. C'était avant. Si je n'inclue pas loadVideoById () ou playVideo (), cela fonctionne. Idéalement, j'aimerais que cela fonctionne avec loadVideoById ().

10
David

Je me suis cogné la tête contre l'ordinateur pendant des heures pour tenter de résoudre celui-ci ... Voici ce que j'ai trouvé.

Cela est dû à la limitation draconienne iOS d'Apple: les pages Web ne peuvent commencer à lire du contenu audio/vidéo que si elles répondent directement aux commentaires des utilisateurs. (Notez que cette limitation n’affecte que le premier heure de lecture de l’audio/vidéo sur une page.)

Habituellement, pour contourner la limitation d’Apple, il suffit de s’assurer que votre appel à play () a lieu directement dans un gestionnaire d’événements (par exemple, un gestionnaire de clics). Cela fonctionne pour l'API Web Audio et les vidéos HTML5 normales - mais quelque chose à propos du lecteur YouTube empêche cela de fonctionner pour YouTube.

Par conséquent, la solution pour YouTube consiste apparemment à demander à l'utilisateur de cliquer sur la vidéo YouTube elle-même pour lancer la lecture. À partir de ce moment, vous pouvez le contrôler à l’aide de l’API iframe de YouTube (lecture, pause, recherche, etc.). Cependant, vous ne pouvez pas contrôler la vidéo YouTube à l'aide de l'API tant que après l'utilisateur n'a pas cliqué sur la vidéo.

Pour une expérience utilisateur à toute épreuve, vous pouvez masquer l’ensemble de votre interface utilisateur contrôlant le lecteur et demander aux utilisateurs de cliquer sur la vidéo YouTube elle-même pour lancer la lecture. Ensuite, une fois que l'utilisateur a cliqué une fois sur la vidéo, vous pouvez activer votre interface utilisateur. Bien entendu, vous ne devez concevoir ceci que pour l'appliquer à iOS.

Merci pour les maux de tête, Apple!

7
Adrian Holovaty

J'ai eu un problème similaire et j'ai creusé un peu. Apple a supprimé la possibilité de lire automatiquement les éléments incorporés via des scripts, afin que l'utilisateur final n'utilise pas leurs données de manière inattendue. L'utilisateur doit déclencher le bouton de lecture lui-même.

Le meilleur moyen de résoudre ce problème serait de vérifier si l'utilisateur est sur mobile ou sur le bureau et de définir une variable (true/false).

C'est ce que j'ai fait

var mobileDevice = false;
if(typeof window.orientation !== 'undefined'){
	var mobileDevice = true;
}

if(!mobileDevice) ytPlayer.playVideo();

Espérons que cela aide.

Source (https://developer.Apple.com)

Pour empêcher les téléchargements non sollicités sur les réseaux cellulaires chez média intégré ne peut pas être lu automatiquement dans Safari le iOS: l'utilisateur lance toujours la lecture.

Plus de réponses ici - L'API YouTube ne fonctionne pas avec iPad/iPhone/périphérique non Flash

5
Junior

Si le problème est ce que les deux autres réponses (Adrian et Junior) disent, il devrait être facilement résolu en accédant à UIWebView (ou WKWebView) et en activant le drapeau mediaPlaybackRequiresUserAction. Cela peut être fait si vous avez lancé votre propre solution ou si vous utilisez le cadre officiel ( https://github.com/youtube/youtube-ios-player-helper ).

Rapide

let playerView = YTPlayerView()
playerView.webView.mediaPlaybackRequiresUserAction = false
1
ABeanSits

J'ai rencontré le problème après l'installation d'une application audio DPS sur mon ordinateur portable. Les applications ont modifié mon pilote audio existant sur leurs "Haut-parleurs (Digital Power Station)".

En lisant a Reddit post, je remplace le périphérique audio par mon ordinateur portable. Ainsi, le problème résolu pour moi.

0
AR Rose