programing

'HTMLMediaElement'에서 'play'를 실행하지 못함: API는 사용자 제스처로만 시작할 수 있습니다.

telecom 2023. 10. 2. 10:57
반응형

'HTMLMediaElement'에서 'play'를 실행하지 못함: API는 사용자 제스처로만 시작할 수 있습니다.

AngularJs에 SoundManager 2를 사용하는 음악 재생 페이지를 만들고 있습니다.재생할 노래 URL을 얻기 위해 원격 API를 사용하고 있습니다.각도음 관리자2 클릭 이벤트 핸들러를 향상시켰습니다.

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

내가 부품을 추가한 곳은scope.loadFunction(song,callback)그리고 이 함수가 노래 URL을 로드한 후 콜백을 호출하여 각음 관리자2에게 컨트롤을 되돌려 줍니다.

문제는 안드로이드용 크롬에서 다음과 같은 오류가 발생한다는 것입니다.

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

노래에 처음부터 URL이 있고 비동기 로딩을 사용하지 않으면 발생하지 않습니다.

그것에 대한 해결책이 있습니까?

저는 크롬 재생 소리를 실험해 봐야 했습니다.사용자의 제스처(클릭 등) 후에도 1000ms 동안 대기하고 소리가 재생되지 않으면 위의 예외를 두는 것으로 나타났습니다.저의 경우 비동기 트랙 URL 로딩에서 문제가 발생했습니다.

그러나 첫 번째 트랙이 재생된 후 크롬은 이 1000ms 지연에 더 이상 신경쓰지 않으며 원하는 시간 초과로 프로그래밍 방식으로 재생을 호출할 수 있다는 사실도 밝혀졌습니다.

따라서 사용자가 트랙을 처음 클릭한 후 원하는 트랙 URL을 로드한 후 정적 리소스에서 거의 0초 길이의 음소거된 마이크로 사운드를 재생하는 것이 해결책이었습니다.

도움이 되거나 다른 해결책을 찾길 바랍니다.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
  webSettings.setMediaPlaybackRequiresUserGesture(false);
}

이 솔루션을 soundmanager2에 내장한 방법은 다음과 같습니다.

함수 만들기:

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

그런 다음 재생 지시어를 사용합니다.

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();
                    }
                });
            });
        }
    };
}
]);

저 같은 경우는 sound manager.play는 비동기 호출을 서버로 보내 트랙 URL을 가져오는 코드 조각을 포함합니다.이로 인해 문제가 발생했습니다.

도움이 되길 바랍니다.

안드레이바우트의 해결책과 비슷합니다.제가 이 문제를 해결한 방법은 다음과 같습니다.내가 사용하고 싶은 모든 소리를 로드/일시정지하는 기능을 작성했습니다.이 기능은 클릭 시 호출됩니다.이 클릭은 매우 중요합니다.이는 사용자의 제스처가 필요합니다.

$("#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();
}

모든 소리를 재생하고 바로 일시 중지하면 "클라이언트 제스처 후에 로드"되며, 이후에 프로그래밍 방식으로 호출/재생할 수 있습니다.도움이 되길 바랍니다.

언급URL : https://stackoverflow.com/questions/32424775/failed-to-execute-play-on-htmlmediaelement-api-can-only-be-initiated-by-a-u

반응형