2012-04-08 34 views
42

Tôi đang sử dụng ổ cắm làm proxy cho MediaPlayer để tôi có thể tải xuống và giải mã âm thanh mp3 trước khi ghi vào ổ cắm. Điều này tương tự như ví dụ được hiển thị trong ứng dụng tin tức NPR tuy nhiên tôi đang sử dụng ứng dụng này cho tất cả phiên bản Android 2.1 - 4 atm.Android - Kích thước bộ đệm MediaPlayer trong ICS 4.0

đang NPR StreamProxy - http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java

Vấn đề của tôi là phát lại là nhanh chóng cho 2,1-2,3, nhưng dữ liệu trong Android 4.0 ICS bộ đệm MediaPlayer quá nhiều trước khi sa thải người nghe onPrepared.

Một số lượng ví dụ về dữ liệu ghi vào Socket OutputStream trước onPrepared():

On SGS2 với 2.3.4 - onPrepared() sau ~ 133.920 byte

Trên Nexus S với 4.0.4 - onPrepared() sau ~ 961930 bytes

Điều này cũng xảy ra trên Galaxy Nexus.

Giả lập trình giả lập 4.0 không đệm nhiều dữ liệu như thiết bị 4.0. Bất kỳ ai cũng gặp phải sự cố tương tự với MediaPlayer trên ICS?

EDIT

Đây là cách proxy đang ghi vào ổ cắm. Trong ví dụ này, nó lấy từ một tệp tin CipherInputStream được tải từ một tệp, nhưng điều tương tự cũng xảy ra khi nó được tải từ HttpResponse.

final Socket client = (setup above) 

// encrypted file input stream 
final CipherInputStream inputStream = getInputStream(file); 

// setup the socket output stream 
final OutputStream output = client.getOutputStream(); 

// Writing the header 
final String httpHeader = buildHttpHeader(file.length()); 
final byte[] buffer = httpHeader.getBytes("UTF-8"); 
output.write(buffer, 0, buffer.length); 

int writtenBytes = 0; 
int readBytes; 
final byte[] buff = new byte[1024 * 12]; // 12 KB 

while (mIsRunning && (readBytes = inputStream.read(buff)) != -1) { 
    output.write(buff, 0, readBytes); 
    writtenBytes += readBytes; 
} 

output.flush(); 
output.close(); 

Các HTTP Headers được ghi vào MediaPlayer trước âm thanh ..

private String buildHttpHeader(final int contentLength) { 
    final StringBuilder sb = new StringBuilder(); 

    sb.append("HTTP/1.1 200 OK\r\n"); 
    sb.append("Content-Length: ").append(contentLength).append("\r\n"); 
    sb.append("Accept-Ranges: bytes\r\n"); 
    sb.append("Content-Type: audio/mpeg\r\n"); 
    sb.append("Connection: close\r\n"); 
    sb.append("\r\n"); 

    return sb.toString(); 
} 

Tôi đã nhìn xung quanh cho việc triển khai thay thế nhưng như tôi đã được mã hóa âm thanh và MediaPlayer không hỗ trợ InputStreams như một nguồn dữ liệu tùy chọn duy nhất của tôi (tôi nghĩ ..) là sử dụng một proxy như thế này.

Một lần nữa, điều này hoạt động khá tốt Android 2.1 - 2.3 nhưng trong ICS MediaPlayer đang đệm một lượng lớn dữ liệu này trước khi phát.

CHỈNH SỬA 2:

Kiểm tra thêm cho thấy đây cũng là vấn đề trên SGS2 khi nâng cấp lên Android 4.0.3. Vì vậy, có vẻ như việc thực hiện bộ đệm của MediaPlayer đã thay đổi đáng kể trong 4.0. Điều này là bực bội vì API không cung cấp cách nào để thay đổi hành vi.

CHỈNH SỬA 3:

Lỗi Android được tạo. Hãy thêm nhận xét và ngôi sao có cũng http://code.google.com/p/android/issues/detail?id=29870

EDIT 4:

đang phát lại của tôi là khá chuẩn .. Tôi có gọi start() trên MediaPlayer trong phương pháp của tôi onPrepared().

mCurrentPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
mCurrentPlayer.setDataSource(url); 
mCurrentPlayer.prepareAsync(); 

Đã thử bằng cách chỉ chuẩn bị() và cũng là cách được đề xuất của ajacian81 nhưng không có kết quả.

tôi nên nói thêm rằng thời gian gần đây một nhân viên của Google đã trở lại với tôi về câu hỏi của tôi và khẳng định rằng kích thước bộ đệm đã được cố ý tăng trong ICS (đối với nội dung HD). Nó đã được yêu cầu để các nhà phát triển API để thêm khả năng thiết lập một kích thước bộ đệm trên MediaPlayer.

Mặc dù tôi nghĩ rằng yêu cầu thay đổi API này đã được khoảng trước khi tôi đến cùng vì vậy tôi sẽ không khuyên bất cứ ai để giữ hơi thở của họ.

+1

Wow! cùng một vấn đề! Nexus S. Quá nhiều bộ đệm với MediaPlayer – Alexis

+0

Có thể đáng ghi nhật ký này dưới dạng lỗi với các nhà phát triển Android. –

+3

Vui lòng gắn dấu sao cho lỗi Android mà tôi đã gửi để giúp tính năng này hiển thị - https://code.google.com/p/android/issues/detail?id=29870 – denizmveli

Trả lời

2

Nó sẽ có thể để xem mã nơi bạn đang bắt đầu() ing các MediaPlayer?

Bạn đang sử dụng STREAM_MUSIC âm thanh loại dòng?

player.setAudioStreamType(AudioManager.STREAM_MUSIC); 

Bạn cũng đã thử nghiệm giữa player.prepareAsync(); và player.prepare() ;?

Có một vấn đề tương tự năm ngoái tôi nhớ, nơi mà các giải pháp là: bắt đầu, tạm dừng và sau đó onPrepared để bắt đầu():

player.setAudioStreamType(AudioManager.STREAM_MUSIC); 
player.setDataSource(src); 
player.prepare(); 
player.start(); 
player.pause(); 
player.setOnPreparedListener(new OnPreparedListener() {  
@Override 
       public void onPrepared(MediaPlayer mp) { 
        player.start();     
       } 
      }); 

khó có thể sửa chữa trong trường hợp này, nhưng trong khi bạn đang quay bánh xe của bạn điều này có thể có giá trị một shot.

+0

Cảm ơn bạn đã trả lời. Rất tiếc, nó không khắc phục được sự cố của tôi. Ngẫu nhiên, vấn đề bạn đang gặp phải là yêu cầu thực hiện điều này là gì? – denizmveli

+0

@TheModernInk Những khoảng trống dài trong bộ đệm, ngay cả khi kết nối WIFI rất nhanh. – ajacian81

Các vấn đề liên quan