使用 FFMPEG 的 ASP.NET Core 5.0 MVC HLS 转码

Posted

技术标签:

【中文标题】使用 FFMPEG 的 ASP.NET Core 5.0 MVC HLS 转码【英文标题】:ASP.NET Core 5.0 MVC HLS Transcoding using FFMPEG 【发布时间】:2021-12-18 22:58:59 【问题描述】:

概述

我目前正在使用 ASP.net Core REST Server 开发媒体流服务器。我目前正在使用 .net 5.0 和 ASP.net Core MVC

我需要什么

我需要能够动态降低原始视频文件的分辨率。例如从 1080p 到 720p。此外,我还需要能够使媒体文件能够根据客户端功能转码为不同的编码。

我的尝试

我一直在寻找能够完成这项壮举的图书馆,但我似乎找不到。我认为 FFMpeg 能够做到这一点。我知道这是可能的,因为像 plex 和 emby 这样的应用程序似乎可以管理这个。'

C#

public static FileStream GetTranscodedStream(string requestedUser, string path, int targetResolution, int targetBitRate)

    string directoryOutput = Directory.CreateDirectory(Path.Combine(Paths.TempData, $"stream_requestedUser")).FullName;
    string fileOutput = Path.Combine(directoryOutput, $"v_tpath-rtargetResolution.m3u8");
    string exe = Directory.GetFiles(Paths.FFMpeg, "ffmpeg*", SearchOption.AllDirectories)[0];
    string arguments = $"-i \"media.PATH\" -bitrate targetBitRatek -f hls -hls_time 2 -hls_playlist_type vod -hls_flags independent_segments -hls_segment_type mpegts -hls_segment_filename \"Path.Combine(directoryOutput, $"stream_tpath-rtargetResolution%02d.ts")\" \"fileOutput\"";
    Process process = new()
    
        StartInfo = new()
        
            FileName = exe,
            Arguments = arguments,
            UseShellExecute = true,
        ,
        EnableRaisingEvents = true,
    ;
    process.Start();
    return new(fileOutput, FileMode.Open);


[HttpGet("tmdb/user/video/transcoded")]
public IActionResult GetMovieStream(string tmdb, string user, int resolution, int bitrate)

    MediaBase movie = MovieLibraryModel.Instance.GetMovieByTMDB(tmdb);
    var transcoded = GetTranscodedStream(user, movie.PATH, resolution, bitrate);
    long fileSize = new FileInfo(movie.PATH).Length;
    Response.Headers.Clear();
    Response.ContentLength = fileSize;
    Response.Headers.Add("Accept-Ranges", $"bytes");
    Response.Headers.Add("Content-Range", $"bytes 0-fileSize/fileSize");
    activeStreams.Add(Users.Instance.Get(user), timer);
    return File(transcoded, "application/x-mpegURL", true);

html

<link rel="stylesheet" href="/assets/lib/video.js/video-js.css">
    <video id="vid1" class="videojs vjs-default-skin" controls data-setup="" preload="auto">
        <source src="http://127.0.0.1:3208/api/get/movies/299687/dcman58/video/transcoded?resolution=480&bitrate=4800" type="application/x-mpegURL">
    </video>

javascript

var player = videojs('vid1');
player.play();

错误

ERROR 416: Range Not Satisfiable "http://127.0.0.1:3208/api/get/movies/299687/dcman58/video/transcoded?resolution=480&bitrate=4800"

【问题讨论】:

【参考方案1】:

你的问题在于这一行:

Response.Headers.Add("Content-Range", $"bytes 0-fileSize/fileSize");

这是错误描述:https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416

我怀疑您处理问题的方法有误。 FFMPEG 编码需要运行完成才能开始向客户端提供任何数据。您无法即时从 FFMPEG 检索输出。

我无法从您的代码中判断文件是否已经转换并在您尝试返回它们时在磁盘上;如果是这样,只需返回文件本身而不指定范围,返回中的 "application/x-mpegURL" 部分将为您带来魔力

【讨论】:

以上是关于使用 FFMPEG 的 ASP.NET Core 5.0 MVC HLS 转码的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core mvc 应用程序中的 FFMPEG 录制

csharp 使用ASP.Net转换带有FFMPEG的视频

asp.net 使用FFmpeg将视频转换为mp4格式

ASP.NET Core (.NET Core) and ASP.NET Core (.NET Framework)区别

.Net Core 学习 - ASP.NET Core 概念学习

ASP.NET Core 入门教程 1使用ASP.NET Core 构建第一个Web应用