Tôi có một ứng dụng đang phát các tệp MP3 có sẵn tại URL công khai. Thật không may là máy chủ không hỗ trợ phát trực tuyến, nhưng Android làm cho trải nghiệm người dùng khá chấp nhận được.Vấn đề về phương tiện mạng Jellybean Android
Tất cả hoạt động tốt cho tất cả các nền tảng ngoại trừ Jellybean. Khi yêu cầu MP3, JB yêu cầu cho một Phạm vi-Tiêu đề cho 10 lần. Chỉ sau lần thử thứ 10, nó dường như hoàn nguyên về hành vi cũ. Looks like this already reported issue.
Tôi tìm thấy một SO thread khác nơi giải pháp được khuyến nghị là sử dụng Mã hóa mã hóa: chunked tiêu đề. Nhưng ngay bên dưới có một nhận xét rằng điều này không hiệu quả.
Hiện tại tôi không có quyền kiểm soát bất kỳ tiêu đề phản hồi nào ở trên, nhưng cho đến khi tôi có thể làm điều đó, tôi đã nghĩ để tìm kiếm giải pháp thay thế ở phía máy khách. (Mặc dù vậy, tôi chỉ có thể trả về một Phạm vi Nội dung chứa các chỉ mục từ 0 đến Độ dài Nội dung - 1. Phạm vi Nội dung: byte 0-3123456/3123457).
Những gì tôi đã cố gắng để làm là để thực hiện một giả trực tuyến tại phía khách hàng bởi:
- mở thêm một input stream cho MP3.
- Giải mã các byte đến bằng cách sử dụng JLayer. Tôi tìm thấy giải mã tại this link.
- Gửi các byte mảng được giải mã tới một StreamTrack Audio_ack đã phát.
Các đoạn mã mà không được giải mã có thể được tìm thấy ở đó, tôi đã chỉ sửa đổi nó để nó sẽ nhận được một InputStream:
public byte[] decode(InputStream inputStream, int startMs, int maxMs) throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
float totalMs = 0;
boolean seeking = true;
try {
Bitstream bitstream = new Bitstream(inputStream);
Decoder decoder = new Decoder();
boolean done = false;
while (!done) {
Header frameHeader = bitstream.readFrame();
if (frameHeader == null) {
done = true;
} else {
totalMs += frameHeader.ms_per_frame();
if (totalMs >= startMs) {
seeking = false;
}
if (!seeking) {
// logger.debug("Handling header: " + frameHeader.layer_string());
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
if (output.getSampleFrequency() != 44100 || output.getChannelCount() != 2) {
throw new IllegalArgumentException("mono or non-44100 MP3 not supported");
}
short[] pcm = output.getBuffer();
for (short s : pcm) {
outStream.write(s & 0xff);
outStream.write((s >> 8) & 0xff);
}
}
if (totalMs >= (startMs + maxMs)) {
done = true;
}
}
bitstream.closeFrame();
}
return outStream.toByteArray();
} catch (BitstreamException e) {
throw new IOException("Bitstream error: " + e);
} catch (DecoderException e) {
throw new IOException("Decoder error: " + e);
}
}
Tôi yêu cầu các byte được giải mã trong khối thời gian: bắt đầu với (0, 5000) vì vậy tôi sẽ có một mảng lớn hơn để chơi lúc đầu, sau đó tôi yêu cầu các mảng byte tiếp theo kéo dài hơn một giây: (5000, 1000), (6000, 1000), (7000, 1000), v.v.
Giải mã đủ nhanh và được thực hiện trong một chuỗi khác và khi mảng byte được giải mã khả dụng, tôi đang sử dụng hàng đợi chặn ghi nó vào AudioTrack đang phát trong một chuỗi khác.
Vấn đề là phát lại không trơn tru vì các đoạn không liên tục trong một rãnh (mỗi đoạn liên tục, nhưng được thêm vào trong kết quả AudioTrack khi phát lại một cách cẩu thả).
Để kết thúc:
- Nếu bạn đã tình cờ gặp vấn đề Jellybean này, làm thế nào bạn giải quyết nó?
- Nếu có ai trong số các bạn thử cách tiếp cận của tôi, tôi đang làm gì sai trong mã trên? Nếu đây là giải pháp bạn đã sử dụng, tôi có thể xuất bản phần còn lại của mã.
Cảm ơn!
Cảm ơn bạn đã trả lời ... Tôi không muốn làm theo cách tiếp cận này cho dự án tôi cần, nhưng nếu một ngày nào đó tôi sẽ có thời gian rảnh, tôi có thể thử điều này cho mục đích giáo dục. Vì vậy, các câu hỏi mở vẫn tồn tại (Tất cả đều hoạt động tốt cho tất cả các nền tảng ngoại trừ JellyBean. Khi yêu cầu MP3, JB yêu cầu cho một Phạm vi-Header cho 10 lần. Chỉ sau khi nỗ lực thứ 10 nó dường như trở lại hành vi cũ.) Nếu bạn gặp phải vấn đề này, bạn đã khắc phục điều này như thế nào? Đó là một cái gì đó từ phía máy chủ hoặc là nó phía khách hàng? – gunar
Bạn có thể bao gồm mã của mình cho dòng này không: "Khi yêu cầu MP3, JB yêu cầu cho một Phạm vi-Tiêu đề 10 lần. Chỉ sau lần thử thứ 10 nó có vẻ hoàn nguyên về hành vi cũ". – Matt
Tôi không thêm bất kỳ mã nào cho JB để yêu cầu Phạm vi tiêu đề, vui lòng xem [vấn đề Android được đính kèm] (https://code.google.com/p/android/issues/detail?id=35790). Tất cả đều liên quan đến nó. – gunar