簡體   English   中英

Android mediaPlayer 漸進式下載“對等方重置連接”

[英]Android mediaPlayer Progressive Download "Connection Reset By Peer"

我在使用 android MediaPlayer 時遇到問題,我首先在播放之前將整首歌曲緩存到內存中,然后我決定從我用 SparkJava 編寫的 api 流式傳輸歌曲。 所以現在它工作正常如果我試圖尋找一個加載點,否則它就會停止。 並在 API 服務器中生成:

    org.eclipse.jetty.io.EofException
at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:286)
at org.eclipse.jetty.io.WriteFlusher.flush(WriteFlusher.java:393)
at org.eclipse.jetty.io.WriteFlusher.completeWrite(WriteFlusher.java:349)
at org.eclipse.jetty.io.ChannelEndPoint$3.run(ChannelEndPoint.java:133)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:295)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.io.IOException: Connection reset by peer
at java.base/sun.nio.ch.SocketDispatcher.write0(Native Method)
at java.base/sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:54)
at java.base/sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:113)
at java.base/sun.nio.ch.IOUtil.write(IOUtil.java:79)
at java.base/sun.nio.ch.IOUtil.write(IOUtil.java:50)
at java.base/sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:484)
at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:264)

這是 API 部分使用的代碼:

public static Object postAudioResponse(Request request, Response response) {
    try ( OutputStream os = response.raw().getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(os))
    {
        File mp3 = new File("C:\\FTPServer\\" + request.queryParams("dir"));
        String range = request.headers("Range");
        if (range == null) {
            response.status(200);
            byte[] bytes = Files.readAllBytes(java.nio.file.Paths.get("C:\\FTPServer\\" + request.queryParams("dir")));
            response.header("Content-Type", "audio/mpeg");
            response.header("Content-Length", String.valueOf(bytes.length));
            System.out.println(response.raw().toString());
            HttpServletResponse raw = response.raw();
            raw.getOutputStream().write(bytes);
            raw.getOutputStream().flush();
            raw.getOutputStream().close();
            return raw;
        }
        int[] fromTo = fromTo(mp3, range);
        int length = fromTo[1] - fromTo[0] + 1;
        response.status(206);
        response.raw().setContentType("audio/mpeg");
        response.header("Accept-Ranges", "bytes");
        response.header("Content-Range", contentRangeByteString(fromTo));
        response.header("Content-Length", String.valueOf(length));
        final RandomAccessFile raf = new RandomAccessFile(mp3, "r");
        raf.seek(fromTo[0]);
        writeAudioToOS(length, raf, bos);
        raf.close();
        bos.flush();
        bos.close();
        return response.raw();
    } catch (IOException e) {
        e.printStackTrace();
        response.header("Content-Type", "application/json");
        return gson.toJson(new StandardResponse(StatusResponse.ERROR, e.toString()));
    }
}

這是我的 API HTTP 響應(字符串格式)

HTTP/1.1 206 
Date: Wed, 04 Mar 2020 19:39:45 GMT
Content-Type: audio/mpeg
Accept-Ranges: bytes
Content-Range: bytes 4767443-4775635/8897707
Content-Length: 8193

我嘗試了多種方法,更改標頭,多次驗證標頭,嘗試 ExoPlayer,我什至檢查了 HTTP 部分的 android 源代碼,它似乎是正確的。

安卓代碼:

mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(Api.getSongSource(songName));
mediaPlayer.prepareAsync();

注意:異常發生在我發送包含特定范圍內的內容的新 HTTP 響應之前。 謝謝。

* 更新 *

我在第一個答案中解決了這個問題。

我通過執行以下操作修復了上述錯誤

*客戶端我沒有在android原生SDK中使用mediaPlayer,而是使用了ExoMedia(這是ExoPlayer的接口,但與mediaPlayer具有相同的功能)

*服務器端

使用 ExoMedia 后,我開始注意到一些事情,當我尋找尚未加載的點時,它從該部分播放了很短的時間,可能是 50 毫秒,所以我開始四處挖掘並發現以下內容。

當服務器收到Range的請求時,服務器會查找 from,然后發送帶有數據[From, From + Chunk]的響應。

我的 Chunk 等於 8192,在增加chunk 部分后,我可以注意到這首歌播放的時間更長 因此,不要發送[From, From + Chunk]並等待ExoMedia詢問下一部分。

我發送了整個 [From, End of song]。 這修復了我的錯誤。 .

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM