Corruption de flux Java.mp4 à la fin d'une erreur de réseau vidéo


Veuillez aider, Mon problème est de diffuser des octets à partir de. mp4 avec du code sur cette page http://balusc.blogspot.ru/2009/02/fileservlet-supporting-resume-and.html et c'est presque fait correctement, mais le flux est toujours corrompu à la fin d'un film ex.:

La vidéo dure 57 minutes - un échec de 52 secondes s'est produit avec le message: "Une erreur réseau provoque l'échec du flux en partie.", J'ai essayé de le tester plusieurs fois, je pensais que c'était vraiment un problème de réseau - mais c'est toujours le même. Je supposons qu'il pourrait y avoir un problème spécifique avec le code avec .mp4 pour représenter les octets pour le navigateur.

Toute aide serait appréciée.

Le msg d'erreur dans le navigateur: Une erreur réseau a provoqué l'échec partiel du téléchargement vidéo.

Le problème devrait être dans cette partie du code, maintenant je suppose que le système Linux Ubuntu, peut-être que JVM n'est pas assez d'espace avec une taille de fichier supérieure à 1,6 Go comme C. Trimble mentionné dans les commentaires-je devrais probablement allouer plus de mémoire sur le socket de flux de lecture pour les fichiers ou dans la JVM elle-même, je ne sais pas comment (- Xms, - Xmx):

  private static void copy(RandomAccessFile input, OutputStream output, long start, long length) {
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
    int read;

    try {
      if (input.length() == length) {
        // Write full range.
        Logger.log("length==length read/write "+length);
        while ((read = input.read(buffer)) > 0) {
          output.write(buffer, 0, read);
        }
      } else {
        // Write partial range.
        input.seek(start);
        Logger.log("start length: "+start);
        long toRead = length+start;

        while ((read = input.read(buffer)) > 0) {
          if ((toRead -= read) > 0) {
            output.write(buffer, 0, read);
            Logger.log("toRead -= read read/write "+toRead);
//            output.write(buffer, 0, DEFAULT_BUFFER_SIZE);

          } else { // the end of a movie - ERROR APPEARS HERE !!!
            Logger.log("the end read/write "+toRead);
            output.write(buffer, 0, (int) toRead + read);
//            output.write(buffer, 0, DEFAULT_BUFFER_SIZE);
            break;
          }
        }
      }
    } catch (IOException ex) {
      Logger.log(Arrays.toString(ex.getStackTrace()), "error.log");
      Logger.log(ex.getMessage(), "error.log");
    }
  }

Contenu de la réponse-Plage des journaux commencés à partir de 1-st à la fin quand il tombe:

2014-12-27 17:55:625 Contenu-Plage: octets 1784938496-1787737811/1787737812 2014-12-27 17:55:645 Contenu-Gamme: octets 262144-1787737811 / 1787737812 2014-12-27 17:55:795 Contenu-Gamme: octets 1048576-1787737811 / 1787737812 2014-12-27 17:55:190 Contenu-Gamme: octets 1572864-1787737811 / 1787737812 2014-12-27 17:55: 676 Contenu-Plage: octets 2097152-1787737811 / 1787737812 2014-12-27 17:55:195 Contenu-Gamme: octets 2621440-1787737811 / 1787737812 2014-12-27 17:55:721 Contenu-Gamme: octets 3145728-1787737811 / 1787737812 2014-12-27 17:55:421 Contenu-Gamme: octets 786432-1787737811 / 1787737812 2014-12-27 17:55:992 Contenu-Gamme: octets 1409024-1787737811 / 1787737812 2014-12-27 17:55:453 Contenu-Gamme: octets 1835008-1787737811 / 1787737812 2014-12-27 17:55:34 Contenu-Gamme: octets 2359296-1787737811/1787737812 2014-12-27 17:55:757 Contenu-Gamme: octets 2883584-1787737811 / 1787737812 2014-12-27 17: 55: 340 Contenu-Gamme: octets 5767168-1787737811 / 1787737812

Tous les en-têtes de FireBug Net tool-response:

Accept-Ranges   bytes
Content-Disposition inline;filename="True.Detective.S01E02.BDRip.720p.mp4"
Content-Length  1769137613
Content-Range   bytes 1572864-1770710476/1770710477
Content-Type    video/mp4
Date    Sat, 27 Dec 2014 17:53:54 GMT
Etag    True.Detective.S01E02.BDRip.720p.mp4_1770710477_1419450095000
Expires Sat, 03 Jan 2015 17:53:54 GMT
Last-Modified   Wed, 24 Dec 2014 19:41:35 GMT
Server  Apache-Coyote/1.1

En-têtes de requête:

Accept  video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5
Accept-Language ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Connection  keep-alive
Cookie  _ga=GA1.2.1399057170.1418569894; ci_session=a%3A5%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22013f5e68900cbd78accb95573968b6f3%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A12%3A%22109.173.78.7%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A72%3A%22Mozilla%2F5.0+%28Windows+NT+6.3%3B+WOW64%3B+rv%3A34.0%29+Gecko%2F20100101+Firefox%2F34.0%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1419680981%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3B%7D4785741ee92c92e18475135f708e4283; PHPSESSID=s0cbpcnbqegb5u3312joe36510; _gat=1; _ym_visorc_27490695=w
Host    test.fast-seasons.ru:8080
Range   bytes=1572864-
Referer http://test.fast-seasons.ru:8080/tv/streaming?token=549ef20cd8a82
User-Agent  Mozilla/5.0 (Windows NT 6.3; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0

Sortie dans les journaux avant l'échec-semble être bon avant l'échec du système/JVM en raison d'une allocation de fichier ou de mémoire plus importante:

2014-12-27 23:44:783 toRead -= read read/write 5792296
2014-12-27 23:44:783 toRead -= read read/write 5783080
2014-12-27 23:44:783 toRead -= read read/write 5773864
2014-12-27 23:44:783 toRead -= read read/write 5767168

Parfois, dans les journaux personnalisés, je vois ce qui suit exception:

2014-12-28 13:47:522 [org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:413), org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk
.java:342), org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:438), org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:
426), org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91), ru.fastseasons.streaming.StreamServlet.copy(StreamServlet.java:446)
, ru.fastseasons.streaming.StreamServlet.processRequest(StreamServlet.java:329), ru.fastseasons.streaming.StreamServlet.doGet(StreamServlet.java:100), javax.
servlet.http.HttpServlet.service(HttpServlet.java:620), javax.servlet.http.HttpServlet.service(HttpServlet.java:727), org.apache.catalina.core.ApplicationFil
terChain.internalDoFilter(ApplicationFilterChain.java:303), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208), org.ap
ache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220), org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java
:122), org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170), org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.jav
a:98), org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950), org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.jav
a:116), org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408), org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11P
rocessor.java:1040), org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607), org.apache.tomcat.util.net.JIoEndpoint$
SocketProcessor.run(JIoEndpoint.java:313), java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145), java.util.concurrent.ThreadPoolEx
ecutor$Worker.run(ThreadPoolExecutor.java:615), java.lang.Thread.run(Thread.java:745)]
2014-12-28 13:47:522 null

Bien sûr, j'ai regardé la ligne 446 et j'ai vu la variable read passer en argument 3d pour lire le nombre d'octets qu'elle contient, mais il ne devrait pas y avoir de problèmes de programme avec cela, car read var est toujours >0 à travers la condition de boucle while.

Le comportement étrange que je suppose est que cela se produit avec des fichiers de format .mp4 plus grand 1Gb, peut - être que c'est l'étouffement de la mémoire Linux ou JVM-je ne sais pas et je ne sais pas comment le tester. J'ai aussi essayé de regarder ulimit-r - l

real-time priority              (-r) 95
max locked memory       (kbytes, -l) unlimited

Il y a en fait 3 lignes dans les journaux pour chaque flux mp4 / vidéo ( lorsque la vidéo est lue via le navigateur Chrome sous Windows) - semble être tout à fait normal, le voici:

2014-12-28 22:29:167 Content-Range: bytes 0-1180454117/1180454118
2014-12-28 22:29:168 Content-Length: 1180454118
2014-12-28 22:29:601 Content-Range: bytes 1178816938-1180454117/1180454118
2014-12-28 22:29:601 Content-Length: 1637180
2014-12-28 22:29:768 Content-Range: bytes 1178816986-1180454117/1180454118
2014-12-28 22:29:769 Content-Length: 1180454070

Fonctionne dans Chrome, thx à EJP, mais toujours des problèmes dans FF.

Modifications implémentées dans le code après la correction @EJP:

long toRead = length;

while (toRead > 0 && (read = input.read(buffer, 0, (int)Math.min(buffer.length, toRead))) > 0)
{
    output.write(buffer, 0, read);
    toRead -= read;
}
Author: Arthur Kushman, 2014-12-23

1 answers

long toRead = length+start;

Le problème est ici. Il devrait être:

long toRead = length;

Cependant, votre code peut être considérablement simplifié:

while (toRead > 0 && (read = input.read(buffer, 0, (int)Math.min(buffer.length, toRead))) > 0)
{
    output.write(buffer, 0, read);
    toRead -= read;
}

E & OE

 0
Author: user207421, 2014-12-30 22:15:11