Mic*_*l B 7 android cordova cordova-media-plugin
我使用cordova 6.4.0与cordova-plugin-media用于在Android应用程序流媒体广播站.不幸的是,有一种情况,应用程序不再正常响应.
假设用户想要流式传输无线电,但是当流加载时,他想要中止它(例如,因为流已关闭,或者需要很长时间才能加载).
在这种情况下,我无法取消该过程!
media = new Media("http://direct.franceinfo.fr/live/franceinfo-midfi.mp3?ID=f9fbk29m84", mediaPlayerSuccess, mediaPlayerFail, mediaPlayerStatus);
media.play();
Run Code Online (Sandbox Code Playgroud)
现在我想取消缓冲流的过程,但我无法做到.功能:
media.pause();
media.stop();
Run Code Online (Sandbox Code Playgroud)
在ADB日志中抛出错误消息并调用mediaPlayer-onError回调.
D/AudioPlayer( 3362): AudioPlayer Error: pausePlaying() called during invalid state: 1
...
D/AudioPlayer( 3362): AudioPlayer Error: stopPlaying() called during invalid state: 1
Run Code Online (Sandbox Code Playgroud)
该media.release()命令停止加载流!然而,只是在不停止流的情况下释放流,会导致其他相当大的问题:
如果你调用media.release()媒体对象,大多数时候系统反应非常慢并且挂起几秒钟.但如果经常这样做,系统会完全冻结.这意味着它不再接受远程控制命令.Adb-log仍然有效,但在这种情况下不会显示任何错误.只有POWER按钮仍在工作(它锁定并解锁屏幕).从这种搞砸状态恢复的唯一方法是重启设备.
如果没有播放,我该如何取消媒体流呢?这是插件中的错误吗?
附件是代码片段,我用它来处理媒体流逻辑.如上所述...它基本上有效,但如果你多次调用它会减慢甚至冻结设备.
function radioControl(action, media_src){
//media_src is a webradio-streamurl.
if(action == 'play') {
// Initial Play
if(media === null){
mediaCreateObject(media_src);
}
// If we get PLAY but on antoher station
else if(media.src != media_src){
mediaReleaseRessources();
mediaCreateObject(media_src);
}
//interrupt_timer = false;
if(media === null){
mediaCreateObject(media_src);
}
media.play();
}
else if (action === 'pause') {
//If we get "pause", but it didn't even start yet
if(media._duration == -1){
mediaReleaseRessources();
}
else{
media.pause();
}
}
}
function mediaCreateObject(media_src){
media = new Media(media_src, mediaPlayerSuccess, mediaPlayerFail, mediaPlayerStatus);
}
function mediaReleaseRessources(){
media.release();
}
Run Code Online (Sandbox Code Playgroud)
我发现,这不是 cordova 问题,而是一个8 年前的(!) android-bug,从未修复过。看这里:
https://code.google.com/p/android/issues/detail?id=959
重置或释放未使用的 MediaPlayer 时 MediaPlayer“崩溃”(使调用线程死锁)
基本上问题是:如果您尝试“释放”尚未播放的媒体对象,它将导致调用线程死锁,这会导致我在问题中提到的冻结。不幸的是他们从未修复这个错误,只是将其标记为“过时”。在 Android 5.1.1 中。该错误显然仍然存在。也许他们在以后的版本中修复了它。
我为这个问题做了一个相当丑陋的解决方法,但它有效。基本上我所做的是:我们将每个媒体对象保存在 javaScript 对象中。如果用户在播放时停止它,我们可以停止并删除该对象。但如果它没有播放,我们会将这个媒体对象保留在这个 javaScript 对象中。media_objects = {};
此外,我们还将当前active_media流保存在一个变量中。
如果 cordova 调用mediaPlayerStatusChange回调,我们会循环media_objects并检查“待处理”对象之一的状态现在是否已更改为“正在运行”。- Cordova 只是调用媒体状态更改回调,而不指示任何媒体对象刚刚更改了状态。这是不幸的,所以我们必须检查挂起的“过时”对象之一现在是否开始播放。如果是这样,我们可以停止并释放它。(如果对象实际上正在播放,则停止并释放按预期工作 - 只有当它没有播放时,才会导致崩溃)
function mediaPlayerStatusChange(status){
mediaReleaseRessources();
// handle status change....
// ......
}
function mediaReleaseRessources(){
for(var key in media_objects) {
// We can only stop-and release an object, if it is playing
// If an object started playing, the "_duration"-value is != -1
if(key !== active_media && media_objects[key]._duration != -1) {
media_objects[key].stop();
media_objects[key].release();
delete media_objects[key];
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个解决方案对我有用,但是我仍然对更好、更干净的方式来处理科尔多瓦中的多个媒体流感兴趣。
| 归档时间: |
|
| 查看次数: |
1216 次 |
| 最近记录: |