2013-04-09 22 views
5

benim sorunum bu şekilde boşta devlet gitmem sadece android 4.2.2android mediaplyer seekTo içeride

ortaya çıkıyormuş gibi görünüyorsa onPrepared> ve onPrepared içinde seekTo denir, ama üzerinde Bu android versiyonu mediaplayer

döndürür "dosyasının geçmiş sonuna aramaya girişimi: istek = {int> 0}, DURATION ms = 0"

ve hiçbir nokta olmadığı için, baştan oynamaya başlar nerede bunu yakalayabilir, ne de dinleyici olabilir, sadece bu mesajı günlüğe yazar, gerçekten buna tepki veremem. Hatta yabancı değil ne

I) onPrepared içinde mediaPlayer.getDuration() (ararsanız bu uygun değer ve döndüren değil 0.

bunu bir mediaplayer hata olduğunu ya da nerede daha iyi bir yer olduğunu düşünüyor musunuz seekTo arama? ya da seekTo bilmek için nasıl bir yol başarısız oldu? Eğer mevcut pozisyonu istenilen pozisyondan daha küçük ise periyodik olarak kontrol etmekten kaçınmak ve bu yaklaşımın birçok farklı problemi olduğu için aramayı denemek istiyorum.

o pürüzsüz akışlı video içeriğinde İşte

cevap

5

Şu anda aynı soruna bir çözüm bulmaya çalışıyorum. Şimdiye kadar gördüğüm en iyi şey şu şekildedir. 4.2

Aşağıdaki çağrı arka alınan fark ettik:

1)() onVideoSizeChanged - yükseklik ve genişlik 0
2) onPrepared = burada()
3) onVideoSizeChanged() - uygun yükseklik ve genişlikler

Müzikçalar henüz hazırlanmadığı için seekTo in (1) 'i arayamazsınız. İçinde seekTo ararsanız

sen belirtildiği gibi, (2) medya oynatıcı uyarı

yalnızca (3) MediaPlayer.start() olmuştur alırsanız "dosyasının geçmiş sonuna aramaya girişimi" üretir aradı, ama bu noktada seekTo() başarıyla çağırabilirsiniz.

MediaPlayer mMediaPlayer = new MediaPlayer(); // + some initialisation code 
boolean mVideoSizeIsSet = false; 
boolean mMediaPlayerIsPrepared = false; 

public void onPrepared(MediaPlayer mediaplayer) { 
    Log.d(TAG, "onPrepared called"); 
    mMediaPlayerIsPrepared = true; 

    if (mVideoSizeIsSet) { 
     mMediaPlayer.seekTo(); 
    } 

    mMediaPlayer.start() 
} 


public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { 
    Log.d(TAG, "onVideoSizeChanged called"); 

    if (width == 0 || height == 0) { 
     Log.d(TAG, "invalid video width(" + width + ") or height(" + height + ")"); 
    } else { 

     mVideoSizeIsSet = true; 

     if (mMediaPlayerIsPrepared) { 
      mMediaPlayer.seekTo(); 
     } 
    } 
} 

(Ben şahsen boolean korumaları kullanımını sevmiyorum, ama sdk ile sağlanan medya oynatıcı numunesi bakarsanız, benzer bir şey yapar). cihazlar/OS sürümleri aralığında

Deneme, bu genel bir çözüm sağlar. Ancak, 4.2 ile bir hata var. MMediaPlayer.start() öğesine yapılan çağrı, videonun ilk birkaç karesinin seekTo() gerçekleşmeden önce oynatılmaya başlamasına neden oluyor gibi görünüyor, bu durum benim durumum için zorlukla görülebilir, ancak sizin için daha görünür olabilir. Şu anda onSeekComplete() olayını alana kadar yüzey görünümümü bir şekilde gizlemeye çalışıyorum, ancak bu ideal değil.

kimse bunu duymak isteriz tüm OS sürümleri çalışan daha iyi bir çözüm varsa.

+0

Robin'in yanıtından sonra, medya oynatıcı kaynak kodunu, süre değerinin sonunda ayarlandığı yere kadar izlemeye çalıştım. Bir AwesomePlayer yapısına sahip olan ve mDurationUs üyesinin değerini koruyan görünen StageFrightPlayer sınıfına baktım. Bu, initAudioDecoder veya initVideoDecoder için bir çağrı yapıldığında ayarlanmış gibi görünüyor. İdeal çözüm, bu iki fonksiyondan birinin java MediaPlayer.start() işlevini çağırmaya gerek olmadan çağrılmasına neden olacak sanırım? – Simon

+0

Ayrıca bu bilgiyi Android'de bir yorum olarak ekledim [Yayın 54112] (http://code.google.com/p/android/issues/detail?id=54112). – Simon

+0

Bu benim için çalışıyor, teşekkürler! – Eric

0

kaynak kodu geçerli:

418 status_t MediaPlayer::seekTo_l(int msec) 
419 { 
420  ALOGV("seekTo %d", msec); 
421  if ((mPlayer != 0) && (mCurrentState & (MEDIA_PLAYER_STARTED | MEDIA_PLAYER_PREPARED | MEDIA_PLAYER_PAUSED | MEDIA_PLAYER_PLAYBACK_COMPLETE))) { 
422   if (msec < 0) { 
423    ALOGW("Attempt to seek to invalid position: %d", msec); 
424    msec = 0; 
425   } else if ((mDuration > 0) && (msec > mDuration)) { 
426    ALOGW("Attempt to seek to past end of file: request = %d, EOF = %d", msec, mDuration); 
427    msec = mDuration; 
428   } 
429   // cache duration 
430   mCurrentPosition = msec; 
431   if (mSeekPosition < 0) { 
432    getDuration_l(NULL); 
433    mSeekPosition = msec; 
434    return mPlayer->seekTo(msec); 
435   } 
436   else { 
437    ALOGV("Seek in progress - queue up seekTo[%d]", msec); 
438    return NO_ERROR; 
439   } 
440  } 
441  ALOGE("Attempt to perform seekTo in wrong state: mPlayer=%p, mCurrentState=%u", mPlayer.get(), mCurrentState); 
442  return INVALID_OPERATION; 
443 } 

Sana süresi alanını başlatmak zorlamak için mediaplayer örneğini izin önce) getDuration (çağırmak öneriyoruz. Aksi halde, lütfen seekTo() 'den önce start()' ı çağırmaya çalışın, hatta start() 'dan bir süre sonra seekTo() öğesini çağırın.

+1

Cevabınız için teşekkür ederiz, maalesef getDuration() önce seekBu aramayı denemeyin, seek() önce seekTo() da yardımcı olmaz ve bir gecikme ile seekTo çağrısı güvenilir bir çözüm değildir. –

2

Bu, NuPlayer uygulamasında bir sorundur. AwPlayPlayer ile yerel oynatmanın aksine NuPlayer uygulamasının uygun bir hazırlık uygulaması yoktur. Ağ bağlantısı, sadece süre() çağrıldığında ve sürenin bilinmesinden sonra kurulur. Süre, süre 0 ise, süre kontrolünü atlayarak çözülebilir, daha önce denedim.

İlgili konular