2016-12-15 73 views
6

我正在使用cordova 6.4.0cordova-plugin-media流式无线电台在Android应用程序。不幸的是,有一种情况是应用程序没有正确响应。我们假设用户想要流式放大器,但是当流加载时,他想中止它(例如,因为流被关闭,或者需要很长时间才能加载)。Cordova媒体插件 - 停止流式传输不工作 - 释放()冻结设备

在这种情况下,我无法取消该过程!

media = new Media("http://direct.franceinfo.fr/live/franceinfo-midfi.mp3?ID=f9fbk29m84", mediaPlayerSuccess, mediaPlayerFail, mediaPlayerStatus); 
media.play(); 

现在我想取消缓冲流的过程,但我无法。功能:

media.pause(); 
media.stop(); 

正在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 

media.release()命令停止加载流!然而,只是释放流而不停止它,会导致其他相当大的问题:

如果您在媒体对象上调用media.release(),大多数时间系统反应非常缓慢并挂起几秒钟。但如果你经常这样做,系统完全冻结。这意味着它不再支持远程控制命令。 Adb日志仍在工作,但在这种情况下不显示任何错误。只有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(); 
} 
+0

这是离子1或2或任何其他? –

+0

No ionic,just cordova'6.4.0' –

+0

@MichaelB我觉得你必须先调用media.stop(),然后调用media.release()来释放资源。请试试 – Gandhi

回答

3

我发现,这是不是一个科尔多瓦问题,而是一个8年岁(!)Android的错误,这是从来没有固定的。在这里看到:

https://code.google.com/p/android/issues/detail?id=959

MediaPlayer "crash" (deadlocks the calling thread) when resetting or releasing an unused 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]; 
    } 
    } 
} 

该解决方案对我的作品,但我仍然有兴趣在一个更美好,更清洁的方式处理科多瓦的多个媒体流。