无法在 'HTMLMediaElement' 上执行 'play':API 只能由用户手势启动
Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture
我正在做一个音乐播放页面,我用的是SoundManager 2 for AngularJs。
我正在使用遥控器 API 播放歌曲 URL。我增强了 angular-soundmanager2 单击事件处理程序:
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 它调用回调将控制权交还给 angular-soundmanager2。
问题是在 chrome for android 我得到一个错误:
Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.
如果一首歌曲从头开始有 URL 且未使用异步加载,则不会发生这种情况。
是否有任何解决方法?
我不得不尝试 Chrome 播放声音。事实证明,即使在用户手势(例如单击)之后,它也会等待 1000 毫秒,如果没有播放声音,它会抛出上述异常。在我的例子中,问题来自异步轨道 URL 加载。
但事实证明,在播放第一首曲目后,chrome 不再关心这 1000 毫秒的延迟,您可以通过编程方式调用播放,并设置您想要的任何超时时间。
因此,解决方案是在用户第一次点击曲目并加载所需曲目后,从静态资源播放几乎零秒长的微静音 URL。
希望对您有所帮助,或者有人找到了其他解决方案。
以下是我如何将此解决方案嵌入到 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;
}
}
然后在 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();
}
});
});
}
};
}
]);
在我的例子中 soundManager.play 包含一段代码,该代码向服务器发送异步调用以获取曲目 url。这是导致问题的原因。
希望对您有所帮助
类似于andreybavt 的解决方案。这是我解决问题的方法。
我写了一个函数来加载 play/pause 我想使用的所有声音。这个函数叫做 onClick。这个点击非常重要。这将是需要用户的手势。
$("#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();
}
通过立即播放和暂停所有您不会听到的声音,它们将是 "loaded after a client gesture" 并且之后您将能够以编程方式 call/play 它们。
希望这有帮助。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
webSettings.setMediaPlaybackRequiresUserGesture(false);
}
我正在做一个音乐播放页面,我用的是SoundManager 2 for AngularJs。 我正在使用遥控器 API 播放歌曲 URL。我增强了 angular-soundmanager2 单击事件处理程序:
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 它调用回调将控制权交还给 angular-soundmanager2。
问题是在 chrome for android 我得到一个错误:
Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.
如果一首歌曲从头开始有 URL 且未使用异步加载,则不会发生这种情况。
是否有任何解决方法?
我不得不尝试 Chrome 播放声音。事实证明,即使在用户手势(例如单击)之后,它也会等待 1000 毫秒,如果没有播放声音,它会抛出上述异常。在我的例子中,问题来自异步轨道 URL 加载。
但事实证明,在播放第一首曲目后,chrome 不再关心这 1000 毫秒的延迟,您可以通过编程方式调用播放,并设置您想要的任何超时时间。
因此,解决方案是在用户第一次点击曲目并加载所需曲目后,从静态资源播放几乎零秒长的微静音 URL。
希望对您有所帮助,或者有人找到了其他解决方案。
以下是我如何将此解决方案嵌入到 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;
}
}
然后在 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();
}
});
});
}
};
}
]);
在我的例子中 soundManager.play 包含一段代码,该代码向服务器发送异步调用以获取曲目 url。这是导致问题的原因。
希望对您有所帮助
类似于andreybavt 的解决方案。这是我解决问题的方法。 我写了一个函数来加载 play/pause 我想使用的所有声音。这个函数叫做 onClick。这个点击非常重要。这将是需要用户的手势。
$("#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();
}
通过立即播放和暂停所有您不会听到的声音,它们将是 "loaded after a client gesture" 并且之后您将能够以编程方式 call/play 它们。 希望这有帮助。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
webSettings.setMediaPlaybackRequiresUserGesture(false);
}