执行'play'on 'HTMLMediaElement': API只能由用户手势启动
Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture
我正在制作一个音乐播放页面,在这里我使用AngularJs的SoundManager 2。我使用远程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不再关心这1000ms延迟,你可以用任何超时你想要的编程方式调用播放。
所以解决方案是在用户第一次点击曲目后,从静态资源中播放一段几乎零秒长的静音声音,然后加载所需的曲目URL。
希望能有所帮助,或者有人找到其他解决方案。
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;
}
}
在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的解决方案。我是这样解决这个问题的。我写了一个函数,加载播放/暂停所有我想使用的声音。这个函数叫做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();
}
通过播放和暂停立即所有的声音,你将不会听到他们播放,他们将"加载后的客户端手势",你将能够调用/播放他们之后编程。
- SignalR客户端启动连接时如何设置用户
- Ember视图未响应用户启动的事件
- 捕获在Windows应用程序中启动其他应用程序的用户事件
- 当用户单击关闭浏览器时(但不是当用户单击刷新按钮时),JavaScript会确认启动
- 重新启动/刷新时在Google Maps API上保存标记,之后's已被用户拖动.下面的
- 匿名用户无法启动多部分上传.请验证
- 如何在没有用户确认的情况下在iPhone的浏览器中启动音频
- 用户扩展中的自定义命令.js启动 Selenium RC 时无法加载
- 在 iOS 中,哪些 JavaScript 事件符合 HTML5 视频/音频的“用户启动”条件
- blur() 无法以编程方式工作 |但在从用户启动时会这样做
- 从用户离开页面时的位置重新启动计时器
- 如何在用户可视化页面点时启动 jQuery 效果
- 使用 javascript 在用户的机器上启动本地文件
- 等待用户点击而不是页面加载来启动功能
- 用户查看页面后启动CSS3转换
- 定时功能和用户启动功能之间的冲突
- 当用户向下滚动时,在折叠下方启动Flash横幅
- 只有当用户单击链接/按钮时,启动响应才会滑动
- 如何将用户启动的操作传递到iframe中
- 确定给定的 JavaScript 操作是否已由用户启动