javascript - ASP.NET Core 5.0 MVC HLS Transcoding using FFMPEG
问题描述
Overview
I'm currently working on a media streaming server using ASP.net Core REST Server. I'm currently using .net 5.0 and ASP.net Core MVC
What I need
I need to be able to dynamically down-res the original video file. from 1080p to 720p for example. Also I need to be able to make the media file able to be transcoded to a different encoding based on client capabilities.
What I've Tried
I've been looking for a library that can manage this feat, but I can't seem to find one. I thought FFMpeg would be able to do this. I know this is possible because applications like plex and emby seem to manage this.'
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_t{path}-r{targetResolution}.m3u8");
string exe = Directory.GetFiles(Paths.FFMpeg, "ffmpeg*", SearchOption.AllDirectories)[0];
string arguments = $"-i \"{media.PATH}\" -bitrate {targetBitRate}k -f hls -hls_time 2 -hls_playlist_type vod -hls_flags independent_segments -hls_segment_type mpegts -hls_segment_filename \"{Path.Combine(directoryOutput, $"stream_t{path}-r{targetResolution}%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
ERROR 416: Range Not Satisfiable "http://127.0.0.1:3208/api/get/movies/299687/dcman58/video/transcoded?resolution=480&bitrate=4800"
解决方案
Your problem is with this line:
Response.Headers.Add("Content-Range", $"bytes {0}-{fileSize}/{fileSize}");
This is the error description: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416
I suspect you're approaching the problem wrong. The FFMPEG encoding needs to run to completion before you can start serving any data back to the client. You cant retrieve the output from FFMPEG on the fly.
I can't tell from your code whether the files are already converted and on disk at the point that you're trying to return them; if so, just return the file itself without specifying ranges, the "application/x-mpegURL"
part in your return will do the magic for you
推荐阅读
- reactjs - 如何使用 Yarn 安装 react-phone-number-input?
- julia - 在生成命名元组的函数的映射上生成数组的命名元组
- bash - 从文件中的每一行文本创建文件
- scala - 使用 scala 和 slick 在数据库中保存一系列依赖的 db 对象
- python-3.x - 使用 ARIMA 进行预测时出错(python statsmodels)
- android - SDK 版本 28 中的依赖项
- wordpress - 当我添加最大上传时,htaccess 停止工作
- java - 用于 JVM 的沙盒脚本语言?
- javascript - JS 使用新键创建一个新的对象数组
- jquery - 如何检查单击的 li 元素是否具有特定的类