2015-09-06 76 views
22

我正在制作音乐播放页面,其中我使用SoundManager 2 for AngularJs。 我正在使用远程API来获取要播放的歌曲URL。我的增强角soundmanager2单击事件处理程序:未能在'HTMLMediaElement'上执行'播放':API只能由用户手势启动

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调用回调给控制回角soundmanager2。

的问题是,Android版Chrome浏览我得到一个错误:

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

如果一首歌曲从一开始就和异步加载一个URL它不发生,不使用。

是否有任何解决方法?

+0

这是关于此主题的Chrome问题 - https://bugs.chromium.org/p/chromium/issues/detail?id=178297 –

回答

22

我不得不尝试Chrome播放声音。事实证明,即使用户的手势(如点击)等待了1000毫秒,如果没有播放声音,它会抛出上述异常。在我的情况下,问题来自异步跟踪URL加载。

但它也证明,第一个曲目播放后,Chrome不再关心这1000毫秒的延迟,你可以用任何你想要的超时以编程方式调用播放。

因此,解决方案是在用户第一次点击轨道并在加载期望的轨道URL之后,从静态资源播放几乎为零秒的静音。

希望它可以帮助或有人找到其他解决方案。

2

这里是我包埋这个解决方案为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(); 
        } 
       }); 
      }); 
     } 
    }; 
} 
]); 

在我的情况soundManager.play包含一段代码,向服务器发送异步调用以获取跟踪网址。这是造成这个问题。

希望这可以帮助

0

类似于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(); 
} 

通过播放和暂停立即将所有声音,你不会听到他们玩,他们将“装一个客户端手势之后”,您将能够调用/播放它们编程之后。 希望这有助于。

1
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 
    webSettings.setMediaPlaybackRequiresUserGesture(false); 
} 
相关问题