Бесшовное перекодирование отдельных сегментов HLS по требованию.C#

Место общения программистов C#
Ответить
Anonymous
 Бесшовное перекодирование отдельных сегментов HLS по требованию.

Сообщение Anonymous »

Фон
Я хотел реализовать перекодирование по требованию определенных видеоформатов, таких как «.mkv», «.wmv», «.mov» и т. д., чтобы обслуживать их на сервере управления мультимедиа с помощью ASP.NET Core 6.0, C# и ffmpeg.
Мой подход
Подход, который я решил использовать, заключается в предоставлении динамически создаваемого файла .m3u8, который просто создается с использованием выбранной продолжительности сегмента, например 10 секунд и известная продолжительность видео. Вот как я это сделал. Обратите внимание, что решение в настоящее время не реализовано и отброшено:

публичная строка GenerateVideoOnDemandPlaylist(двойная длительность, сегмент int) { двойной интервал = (двойной) сегмент; вар содержимое = новый StringBuilder(); content.AppendLine("#EXTM3U"); content.AppendLine("#EXT-X-VERSION:6"); content.AppendLine(String.Format("#EXT-X-TARGETDURATION:{0}", сегмент)); content.AppendLine("#EXT-X-MEDIA-SEQUENCE:0"); content.AppendLine("#EXT-X-PLAYLIST-TYPE:VOD"); content.AppendLine("#EXT-X-INDEPENDENT-SEGMENTS"); for (двойной индекс = 0; (индекс * интервал) < длительность; индекс++) { content.AppendLine(String.Format("#EXTINF:{0:#.000000},", ((длительность - (индекс * интервал)) > интервал) ? интервал : ((длительность - (индекс * интервал)))) ); content.AppendLine(String.Format("{0:00000}.ts", index)); } content.AppendLine("#EXT-X-ENDLIST"); вернуть содержимое.ToString(); } [HttpGet] [Route("поток/{id}/{разрешение}.m3u8")] общедоступный поток IActionResult (идентификатор строки, разрешение строки) { двойная продолжительность = RetvieveVideoLengthInSeconds(); return Content(GenerateVideoOnDemandPlaylist(duration, 10), "application/x-mpegURL", Encoding.UTF8); } Вот пример того, как выглядит файл .m3u8:

#EXTM3U #EXT-X-ВЕРСИЯ:6 #EXT-X-TARGETDURATION:10 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-PLAYLIST-TYPE:VOD #EXT-X-НЕЗАВИСИМЫЕ-СЕГМЕНТЫ #EXTINF:10.000000, 00000.ц #EXTINF:3.386667, 00001.ц #EXT-X-ENDLIST Итак, игрок запросит 00000.ts, 00001.ts и т. д., и следующим шагом будет их создание по требованию:

public byte[] GenerateVideoOnDemandSegment(int индекс, int длительность, строковый путь) { интервал тайм-аута = 30000; ИНТ TotalWaitTime = 0; Интервал ожидания = 100; byte[] вывод = Array.Empty(); строка исполняемого файла = "/opt/homebrew/bin/ffmpeg"; DirectoryInfo temp = Directory.CreateDirectory(System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName())); строковый формат = System.IO.Path.Combine(temp.FullName, "output-%05d.ts"); используя (Процесс ffmpeg = new()) { ffmpeg.StartInfo.FileName = исполняемый файл; ffmpeg.StartInfo.Arguments = String.Format("-ss {0} ", индекс * продолжительность); ffmpeg.StartInfo.Arguments += String.Format("-y -t {0} ", длительность); ffmpeg.StartInfo.Arguments += String.Format("-i \"{0}\" ", путь); ffmpeg.StartInfo.Arguments += String.Format("-c:v libx264 -c:a aac "); ffmpeg.StartInfo.Arguments += String.Format("-segment_time {0} -reset_timestamps 1 -break_non_keyframes 1 -map 0 ", продолжительность); ffmpeg.StartInfo.Arguments += String.Format("-initial_offset {0} ", индекс * продолжительность); ffmpeg.StartInfo.Arguments += String.Format("-f сегмент -segment_format mpegts {0}", format); ffmpeg.StartInfo.CreateNoWindow = правда; ffmpeg.StartInfo.UseShellExecute = ложь; ffmpeg.StartInfo.RedirectStandardError = ложь; ffmpeg.StartInfo.RedirectStandardOutput = ложь; ffmpeg.Старт(); делать { Thread.Sleep(waitInterval); TotalWaitTime + = интервал ожидания; } while ((!ffmpeg.HasExited) && (totalWaitTime
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»