Вопрос или проблема
[matroska,webm @ 0x63b6772ed400] Ошибка анализа заголовка EBML
[in#0 @ 0x63b6772ed300] Ошибка открытия входного файла: Найдены недопустимые данные при обработке входных данных
Ошибка открытия входного файла dir/~/segment_20.webm.
Ошибка открытия входных файлов: Найдены недопустимые данные при обработке входных данных
Я пытаюсь создать сервер для прямой трансляции с hls и взять видео от клиента с помощью js на 10 секунд, и на сервере я пытаюсь конвертировать его в .ts, так что первый работает правильно, но второй и другие возвращают эту ошибку.
Вот действие контроллера
public async Task<IActionResult> AddStream([FromForm] IFormFile file, string streamId)
{
if (file == null || file.Length <= 0)
{
return BadRequest(" Недопустимый файл.");
}
var tempFilePath = Path.Combine(_env.WebRootPath + "/temps", file.FileName);
try
{
using (var stream = new FileStream(tempFilePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
VideoService.InitializeStream(streamId, _env.WebRootPath + "/assets");
VideoService.ConvertSegmentToTs(streamId, tempFilePath, _env.WebRootPath + $"/assets/{streamId}");
return Ok(new { message = "Сегмент успешно загружен и обработан." });
}
catch (Exception ex)
{
return StatusCode(500, $"Произошла ошибка: {ex.Message}");
}
}
И статическая служба
public static class VideoService
{
private static readonly string ffmpegPath = "/usr/bin/ffmpeg";
private static readonly ConcurrentDictionary<string, string> m3u8Files = new ConcurrentDictionary<string, string>();
public static void InitializeStream(string streamId, string outputDirectory)
{
var directory = Path.Combine(outputDirectory, streamId);
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
var m3u8FilePath = Path.Combine(directory, $"{streamId}.m3u8");
if (!File.Exists(m3u8FilePath))
{
File.WriteAllText(m3u8FilePath, "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-TARGETDURATION:10\n#EXT-X-MEDIA-SEQUENCE:0\n");
m3u8Files[streamId] = m3u8FilePath;
}
}
public static void ConvertSegmentToTs(string streamId, string segmentPath, string outputDirectory)
{
var tsFileName = $"{streamId}_{Path.GetFileNameWithoutExtension(segmentPath)}.ts";
var tsFilePath = Path.Combine(outputDirectory, tsFileName);
var ffmpegArgs = $"-f webm -i \"{segmentPath}\" -c copy -f mpegts \"{tsFilePath}\"";
using (var process = new Process())
{
process.StartInfo.FileName = ffmpegPath;
process.StartInfo.Arguments = ffmpegArgs;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForExit();
if (process.ExitCode == 0)
{
UpdateM3u8File(streamId, tsFileName, outputDirectory);
}
else
{
var error = process.StandardError.ReadToEnd();
Console.WriteLine($"Ошибка FFMPEG для потока {streamId}: {error}");
}
}
}
private static void UpdateM3u8File(string streamId, string tsFileName, string outputDirectory)
{
if (!m3u8Files.TryGetValue(streamId, out var m3u8FilePath))
{
InitializeStream(streamId, outputDirectory);
if (!m3u8Files.TryGetValue(streamId, out m3u8FilePath))
{
Console.WriteLine($"Ошибка: {streamId}");
return;
}
}
var segmentDuration = 10;
var entry = $"#EXTINF:{segmentDuration},\n{tsFileName}\n";
File.AppendAllText(m3u8FilePath, entry);
}
}
Как я могу решить эту проблему?
Ответ или решение
Решение проблемы с созданием .ts файлов при использовании FFMPEG
Согласно вашему описанию проблемы, вы столкнулись с ошибкой, связанной с обработкой входных данных при попытке преобразовать веб-стримы в формат .ts. Эта ошибка возникает при попытке прочитать входной файл, в данном случае вебм-файл, который указывает на недопустимые данные. Давайте подробно разберем возможные причины этого и предложим решения.
Причины ошибки
-
Поврежденный или неправильно закодированный файл: Ошибки с заголовками EBML могут свидетельствовать о том, что файл, который вы пытаетесь обработать, поврежден или не полностью загружен. Проверьте, что файл целиком и корректно записан перед преобразованием.
-
Неправильные параметры ввода: Возможно, параметры, указанные для FFMPEG, неправильно настроены, или у вас устаревшая версия FFMPEG, не поддерживающая некоторые форматы должным образом. Убедитесь, что версия FFMPEG соответствует требованиям для работы с .webm и .ts.
-
Состояние файла в момент обработки: Если файл все еще загружается или не был правильно закрыт после копирования, это также может вызвать проблемы. Убедитесь, что вы полностью завершили процесс записи файла перед его обработкой.
Рекомендации по улучшению кода
Для устранения проблемы с созданием .ts файлов, рассмотрите следующие шаги:
-
Проверка наличия файла: Перед попыткой использовать файл в
ConvertSegmentToTs
, убедитесь, что файл существует и доступен.if (!File.Exists(segmentPath)) { Console.WriteLine($"Файл {segmentPath} не найден."); return; }
-
Логирование ошибок FFMPEG: Расширьте логирование для более четкого понимания ошибки. Вы можете использовать
Console.WriteLine
или другой метод логирования, чтобы сохранять все ошибки.var error = process.StandardError.ReadToEnd(); Console.WriteLine($"FFMPEG Error for Stream {streamId}: {error}");
-
Асинхронная обработка: Рассмотрите возможность использования асинхронных методов для обработки FFMPEG. Это улучшит производительность и отзывчивость вашего приложения.
-
Проверка
ffmpeg
: Убедитесь, что исполняемый файлffmpeg
доступен по указанному пути и настроен правильно. Вы можете проверить это, вызвав командуffmpeg -version
в терминале. -
Использование try-catch для обработки ошибок: Добавьте обработку исключений в метод, который извлекает поток, чтобы перехватывать и обрабатывать возможные исключения.
try { // Код для обработки видео... } catch (Exception ex) { Console.WriteLine($"Ошибка при обработке видео: {ex.Message}"); }
Пример обновленного метода ConvertSegmentToTs
После внесения всех этих улучшений, ваш метод ConvertSegmentToTs
может выглядеть следующим образом:
public static void ConvertSegmentToTs(string streamId, string segmentPath, string outputDirectory)
{
if (!File.Exists(segmentPath))
{
Console.WriteLine($"Файл {segmentPath} не найден.");
return;
}
var tsFileName = $"{streamId}_{Path.GetFileNameWithoutExtension(segmentPath)}.ts";
var tsFilePath = Path.Combine(outputDirectory, tsFileName);
var ffmpegArgs = $"-f webm -i \"{segmentPath}\" -c copy -f mpegts \"{tsFilePath}\"";
using (var process = new Process())
{
process.StartInfo.FileName = ffmpegPath;
process.StartInfo.Arguments = ffmpegArgs;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
try
{
process.Start();
process.WaitForExit();
if (process.ExitCode == 0)
{
UpdateM3u8File(streamId, tsFileName, outputDirectory);
}
else
{
var error = process.StandardError.ReadToEnd();
Console.WriteLine($"FFMPEG Error for Stream {streamId}: {error}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка: {ex.Message}");
}
}
}
Заключение
Изучив и улучшив код, включая выработку логики для обработки ошибок и проверки состояния файлов, вы сможете устранить возникшую проблему с созданием .ts файлов. Убедитесь также, что ваш FFMPEG корректно настроен и доступен на сервере. Не забывайте тестировать каждый этап процесса для более глубокого понимания возможных проблем, которые могут возникнуть.