2015-09-06 16 views
22

Tworzę stronę z muzyką, na której używam SoundManager 2 for AngularJs. Używam zdalnego interfejsu API, aby uzyskać URL utworu do odtworzenia. I wzmocnione procedurę obsługi zdarzenia kliknięcia kątowe-soundmanager2:Nie można wykonać "odtwarzania" w "HTMLMediaElement": interfejs API może zostać zainicjowany tylko gestem użytkownika.

element.bind('click', function() { 
    if (angular.isFunction(scope.loadFunction)) { 
     scope.loadFunction(scope.song, function() { 
      $log.debug('adding song to playlist'); 
      addToPlaylist(scope.song.playDetails); 

     }) 
    } else { 
     $log.debug('adding song to playlist'); 
     addToPlaylist(scope.song); 
    } 
}); 

Gdzie dodaną część, która wywołuje scope.loadFunction(song,callback) i po to funkcja wczytuje piosenkę URL wywołuje wywołania zwrotnego, uzyskując kontrolę z powrotem do kątowego-soundmanager2.

Problem polega na tym, że w Chrome na Androida pojawia się błąd:

Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture. 

nie stanie, jeśli utwór ma URL od początku i async załadunku nie jest używany.

Czy są jakieś obejścia tego problemu?

+0

Oto kwestia Chrome na ten temat - https://bugs.chromium.org/p/chromium/issues/detail?id=178297 –

Odpowiedz

22

Musiałem eksperymentować z dźwiękami gry Chrome. Okazało się, że nawet po gestie użytkownika (np. Kliknięciu) czeka na 1000ms i jeśli nie grał żadnego dźwięku, zgłasza wyjątek powyżej. W moim przypadku problem polegał na asynchronicznym ładowaniu URL-a ścieżki.

Ale okazało się również, że po odtworzeniu pierwszego utworu, chrom już nie przejmuje się tym opóźnieniem 1000ms i można wywoływać programowo programowo z dowolnym czasem oczekiwania.

Rozwiązaniem było odtworzenie mikroprzedłukowego dźwięku o długości niemal zerowej sekundy z zasobów statycznych po pierwszym kliknięciu ścieżki przez użytkownika, a następnie załadowaniu pożądanego adresu URL ścieżki.

Mam nadzieję, że pomaga lub ktoś znajdzie inne rozwiązania.

2

Oto jak ja osadzone ten roztwór do soundmanager2:

utworzyć funkcję:

function playMicroTrack(scope, angularPlayer) { 
if (!scope.$root.isInitialized) { 
    soundManager.createSound({ 
     id: '-1', 
     url: '../../assets/lib/microSound.mp3' 
    }); 
    soundManager.play('-1'); 
    scope.$root.isInitialized = true; 
    } 
} 

Następnie wewnątrz stosowania dyrektywy Play:

ngSoundManager.directive('playAll', ['angularPlayer', '$log', 
function (angularPlayer, $log) { 
    return { 
     restrict: "EA", 
     scope: { 
      songs: '=playAll' 
     }, 
     link: function (scope, element, attrs) { 
      element.bind('click', function (event) { 

       playMicroTrack(scope, angularPlayer); 

       //first clear the playlist 
       angularPlayer.clearPlaylist(function (data) { 
        $log.debug('cleared, ok now add to playlist'); 
        //add songs to playlist 
        for (var i = 0; i < scope.songs.length; i++) { 
         angularPlayer.addTrack(scope.songs[i]); 
        } 

        if (attrs.play != 'false') { 
         //play first song 
         angularPlayer.play(); 
        } 
       }); 
      }); 
     } 
    }; 
} 
]); 

W moim przypadku soundManager.play zawiera fragment kodu, który wysyła asynchroniczne wywołanie do serwera w celu pobrania adresu URL ścieżki. To było przyczyną problemu.

Mam nadzieję, że to pomoże

0

Podobny do rozwiązania andreybavta. Oto, jak rozwiązałem problem. Napisałem funkcję, która ładuje odtwarzanie/wstrzymywanie wszystkich dźwięków, których chcę użyć. Ta funkcja nazywa się onClick. To kliknięcie jest bardzo ważne. Będzie to gest użytkownika wymagany.

$("#myBtn").on("click", function(){ 
setSounds(); 
}); 

function setSounds() { 

    //Play and pause all sounds you want to use 
    var audio1 = $("#mus_1")[0]; 
    var audio2 = $("#mus_2")[0]; 

    audio1.play(); 
    audio1.pause(); 

    audio2.play(); 
    audio2.pause(); 
} 

Poprzez gry i zatrzymując natychmiast wszystko brzmi nie usłyszysz, jak grają, będą one „załadowany po geście klient” i będzie można zadzwonić/odtwarzać je programowo później. Mam nadzieję, że to pomoże.

1
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 
    webSettings.setMediaPlaybackRequiresUserGesture(false); 
} 
Powiązane problemy