web-dev-qa-db-fra.com

API Web .NET Core 2.0 pour le streaming vidéo à partir de FileStream

J'ai trouvé un tas d'exemples qui utilisent des objets qui ne sont pas disponibles pour moi dans mon application et ne semblent pas correspondre à ma version de l'API Web .NET Core. En gros, je travaille sur un projet qui aura <video> tags sur une page Web et souhaitez charger les vidéos à l'aide d'un flux provenant du serveur plutôt que de servir directement les fichiers via un chemin. L'une des raisons est que la source des fichiers peut changer et que les servir via le chemin n'est pas ce que souhaite mon client. J'ai donc besoin d'ouvrir un flux et d'écrire en asynchrone le fichier vidéo.

Pour une raison quelconque, cela produit des données JSON, ce qui est faux. Mais je ne comprends tout simplement pas ce que je dois faire pour envoyer un fichier vidéo en streaming à un <video> tag en HTML.

Code actuel:

[HttpGet]
public HttpResponseMessage GetVideoContent()
{
    if (Program.TryOpenFile("BigBuckBunny.mp4", FileMode.Open, out FileStream fs))
    {
        using (var file = fs)
        {
            var range = Request.Headers.GetCommaSeparatedValues("Range").FirstOrDefault();
            if (range != null)
            {
                var msg = new HttpResponseMessage(HttpStatusCode.PartialContent);
                var body = GetRange(file, range);
                msg.Content = new StreamContent(body);
                msg.Content.Headers.Add("Content-Type", "video/mp4");
                //msg.Content.Headers.Add("Content-Range", $"0-0/{fs.Length}");
                return msg;
            }
            else
            {
                var msg = new HttpResponseMessage(HttpStatusCode.OK);
                msg.Content = new StreamContent(file);
                msg.Content.Headers.Add("Content-Type", "video/mp4");
                return msg;
            }
        }
    }
    else
    {
        return new HttpResponseMessage(HttpStatusCode.BadRequest);
    }
}
6
Bailey Miller

HttpResponseMessage n'est pas utilisé comme type de retour dans asp.net-core il lira cela comme un modèle d'objet et le sérialisera dans la réponse par conception, comme vous l'avez déjà observé.

Heureusement, dans ASP.NET Core 2.0, vous avez

Prise en charge améliorée des en-têtes HTTP

Si un visiteur d'application demande du contenu avec un en-tête de demande de plage, ASP.NET le reconnaîtra et gérera cet en-tête. Si le contenu demandé peut être partiellement remis, ASP.NET sautera et renverra de manière appropriée uniquement l'ensemble d'octets demandé. Vous n'avez pas besoin d'écrire de gestionnaires spéciaux dans vos méthodes pour adapter ou gérer cette fonctionnalité; il est automatiquement géré pour vous.

Alors maintenant, tout ce que vous avez à faire est de retourner le flux de fichiers

[HttpGet]
public IActionResult GetVideoContent() {
    if (Program.TryOpenFile("BigBuckBunny.mp4", FileMode.Open, out FileStream fs)) {        
        return new FileStreamResult(fs, new MediaTypeHeaderValue("video/mp4").MediaType);
    }

    return BadRequest();
}

À partir de là, il suffit désormais de pointer le point final du client vidéo et de le laisser faire sa magie

11
Nkosi