HTML5 - Wie streame ich große MP4-Dateien?


77

Ich versuche, eine sehr einfache HTML5-Seite einzurichten, die ein MP4-Video mit 20 MB lädt. Es scheint, dass der Browser das Ganze herunterladen muss, anstatt nur den ersten Teil des Videos abzuspielen und den Rest zu streamen.

Dieser Beitrag ist das Nächste, was ich bei der Suche gefunden habe ... Ich habe sowohl Handbremse als auch Data Go Round ausprobiert, da keiner der beiden einen Unterschied zu machen schien:

Irgendwelche Ideen, wie das geht oder ob es möglich ist?

Hier ist der Code, den ich verwende:

<video controls="controls">
    <source src="/video.mp4" type="video/mp4" />
    Your browser does not support the video tag.
</video>

Antworten:


146
  1. Stellen Sie sicher, dass sich die moov(Metadaten) vor den mdat(Audio- / Videodaten) befinden . Dies wird auch als "Schnellstart" oder "weboptimiert" bezeichnet. Zum Beispiel hat Handbrake ein Kontrollkästchen "Web Optimized" und ffmpeg und avconv haben die Ausgabeoption -movflags faststart.
  2. Stellen Sie sicher, dass Ihr Webserver den richtigen Inhaltstyp (Video / MP4) meldet.
  3. Stellen Sie sicher, dass Ihr Webserver für die Bearbeitung von Bytebereichsanforderungen konfiguriert ist .
  4. Stellen Sie sicher, dass Ihr Webserver keine gzip- oder deflate-Komprimierung zusätzlich zur Komprimierung in der mp4-Datei anwendet.

Sie können die von Ihrem Webserver gesendeten Header curl -I http://yoursite/video.mp4mithilfe der Entwicklertools in Ihrem Browser ( Chrome , Firefox ) überprüfen (laden Sie die Seite neu, wenn sie zwischengespeichert ist). Der HTTP-Antwortheader sollte Inhaltstyp: Video / MP4 und Akzeptanzbereiche: Byte und keine Inhaltskodierung enthalten : .


Ich habe online keine gute Antwort gefunden ... gibt es eine Anwendung oder eine einfache Möglichkeit, die Moov-Metadaten und ihren Speicherort in der Datei zu überprüfen?
Longda

2
@longda: Zu den Befehlszeilenprogrammen, die die mp4-Dateistruktur anzeigen können, gehören L-SMASH boxdumper, Atomic Parsley -Tund mp4v2 mp4file --dump.
Mark4o

3
Für die Aufzeichnung (hauptsächlich, weil ich ein Idiot bin) rufen Sie über die Befehlszeile wie folgt an: atomicparsley <filename> -T(Die Optionen stehen ganz am Ende). Nochmals vielen Dank für die Hilfe @ mark4o!
Longda

1
@Matheretter: "Schnellstart" oder "Weboptimiert" bedeutet nur, dass das moovam Anfang und nicht am Ende steht. Dies ermöglicht die Suche nach Bytebereichsanforderungen, bevor die gesamte Datei heruntergeladen wird. Wenn dies dazu führt, dass versucht wird, nicht zu funktionieren, suchen Sie in Ihrem Code nach einem Fehler, der die Bytebereichsanforderungen verarbeitet, der nicht verwendet wird, wenn der moovam Ende ist (zu dem Zeitpunkt, als er wusste, welche Bytes er benötigt, hätte er den bereits heruntergeladen ganze Datei). Ich sehe in Ihrer anderen Frage, dass Sie dafür benutzerdefinierten PHP-Code geschrieben haben.
Mark4o

1
Haben Sie eine Referenz dafür?
0xcaff

6

Hier ist die Lösung, mit der ich einen Web-API-Controller in C # (MVC) erstellt habe, der Videodateien mit Byte-Bereichen (Teilanforderungen) bereitstellt. Bei Teilanforderungen kann ein Browser nur so viel Video herunterladen, wie abgespielt werden muss, anstatt das gesamte Video herunterzuladen. Dies macht es weitaus effizienter.

Beachten Sie, dass dies nur in neueren Versionen funktioniert.

var stream = new FileStream(videoFilename, FileMode.Open, FileAccess.Read , FileShare.Read);

var mediaType = MediaTypeHeaderValue.Parse($"video/{videoFormat}");

if (Request.Headers.Range != null)
{
    try
    {
        var partialResponse = Request.CreateResponse(HttpStatusCode.PartialContent);
        partialResponse.Content = new ByteRangeStreamContent(stream, Request.Headers.Range, mediaType);

        return partialResponse;
    }
    catch (InvalidByteRangeException invalidByteRangeException)
    {
        return Request.CreateErrorResponse(invalidByteRangeException);
    }
}
else
{
    // If it is not a range request we just send the whole thing as normal
    var fullResponse = Request.CreateResponse(HttpStatusCode.OK);

    fullResponse.Content = new StreamContent(stream);
    fullResponse.Content.Headers.ContentType = mediaType;

    return fullResponse;
}

2
Diese Antwort ist einfach und handhabt sehr einfaches Streaming. Funktioniert perfekt
James Woodall
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.