Я начал писать программу для математической обработки видео (на Delphi). Пока мне нужно сосредоточиться на алгоритме, и я пытаюсь создать видео файл, которая моя программа откроет и поймёт. Я снял на камеру планшета видео (.mp4), которое хочу обработать. В Delphi XE8 есть TMediaPlayer, но он это видео не понял (“не могу распознать формат по расширению”). Я пробовал через этот сайт перевести видео в другие форматы (в частности avi), но и эти файлы проиграть не получилось: срабатывает какая-то ошибка в TMediaPlayer, хотя исключение не приводит к обрыву работы. Далее я погуглил похожие вещи и скачал отсюда исходники простого видео-проигрывателя на Delphi. Но и он тоже не смог его отобразить, почему-то он думает что видео пустое и занимает 3 секунды (видимо проблема в срабатывании исключения в TMediaPlayer), причём одинаково не работают ни скомпилированный у меня проект, ни екзешник который был вложен в архив. Windows Media Player это видео отобразил нормально. Подскажите как решить проблему.
Мне пока нужно только написать алгоритм обработки, поэтому я не буду сосредотачиваться на подключении кодеков, мне нужно просто получить формат видео файла который мой проект с TMediaPlayer сможет прочесть, так чтобы я имел bitmap-изображение для каждого кадра.
Заодно у меня вопросы по формату видео файлов и сжатию:
1) Количество кадров в секунду для всех форматов одно и то же?
2) Сжатие видео основывается на использовании предыдущего кадра как источника информации о следующем кадре? Хотелось бы примерно представлять “философскую суть” этого сжатия.
"Ты должен сделать добро из зла, потому что его больше не из чего сделать." Р.П. Уоррен
Здравствуйте, Khimik, Вы писали:
K>Мне пока нужно только написать алгоритм обработки, поэтому я не буду сосредотачиваться на подключении кодеков, мне нужно просто получить формат видео файла который мой проект с TMediaPlayer сможет прочесть, так чтобы я имел bitmap-изображение для каждого кадра.
Так просто не получится. Придется в любом случае курить DirectX и через него хватать кадры видео при проигрывании. Более того, кадры, которые ты получишь будут не BMP а чем угодно (зависит от кодека) и, скорее всего не в RGB пространстве (его тоже придется преобразовывать). Ищи библиотеку под DirectX для начала.
Проблема в том, что TMediaPlayer использует MultiMedia API для которого кодеки не пишутся уже 1000 лет.
K>Заодно у меня вопросы по формату видео файлов и сжатию: K>1) Количество кадров в секунду для всех форматов одно и то же?
Нет. От 1 до бесконечности.
K>2) Сжатие видео основывается на использовании предыдущего кадра как источника информации о следующем кадре? Хотелось бы примерно представлять “философскую суть” этого сжатия.
Убрать лишнее. Сжатие видео — сжатие с потерями. Берется 1 ключевой кадр, который сжимается грубо говоря JPEG и пишется в файл. Следующие несколько кадров (сколько — зависит от настроек кодека) есть разница между предыдущим и текущим отталкиваясь от ключевого. Грубо говоря. Если у тебя каждый 5й кадр ключевой, то чтобы получить 4й кадр нужно разжать 1й (ключевой), 2й и 3й кадры. 5й снова будет полным.
Здравствуйте, Khimik, Вы писали:
K>Мне пока нужно только написать алгоритм обработки, поэтому я не буду сосредотачиваться на подключении кодеков, мне нужно просто получить формат видео файла который мой проект с TMediaPlayer сможет прочесть, так чтобы я имел bitmap-изображение для каждого кадра. libav, ffmpeg но если хочется delphi то можно их заюзать через opencv
K>Заодно у меня вопросы по формату видео файлов и сжатию: K>1) Количество кадров в секунду для всех форматов одно и то же?
Разное, указывается внутри файла K>2) Сжатие видео основывается на использовании предыдущего кадра как источника информации о следующем кадре? Хотелось бы примерно представлять “философскую суть” этого сжатия.
Есть разные виды кадров. http://www.compression.ru/video/index_ru.htm
MP>Так просто не получится. Придется в любом случае курить DirectX и через него хватать кадры видео при проигрывании. Более того, кадры, которые ты получишь будут не BMP а чем угодно (зависит от кодека) и, скорее всего не в RGB пространстве (его тоже придется преобразовывать). Ищи библиотеку под DirectX для начала.
Мне сейчас надо сосредоточиться только на алгоритмах, поэтому я постараюсь найти обходный путь, например пусть этот TMediPlayer проиграет видео на экране, а мой код будет копипастить каждый кадр, например через Screen (правда я не нашёл у объекта Screen свойство Canvas). Пока нужно только преобразовать моё видео в формат который этот TMediaPlayer прочитает.
Может TMediaPlayer показать отдельный кадр из видео (застывший)?
"Ты должен сделать добро из зла, потому что его больше не из чего сделать." Р.П. Уоррен
Здравствуйте, Khimik, Вы писали:
K>Мне пока нужно только написать алгоритм обработки, поэтому я не буду сосредотачиваться на подключении кодеков, мне нужно просто получить формат видео файла который мой проект с TMediaPlayer сможет прочесть, так чтобы я имел bitmap-изображение для каждого кадра.
Если тебе нужны только битмапы с каждым кадром — используй консольную программу mpv или mplayer, у них есть опция для указания устройства для вывода, можно указать файлы с изображениями.
Здравствуйте, Khimik, Вы писали:
MP>>Так просто не получится. Придется в любом случае курить DirectX и через него хватать кадры видео при проигрывании. Более того, кадры, которые ты получишь будут не BMP а чем угодно (зависит от кодека) и, скорее всего не в RGB пространстве (его тоже придется преобразовывать). Ищи библиотеку под DirectX для начала.
K>Мне сейчас надо сосредоточиться только на алгоритмах, поэтому я постараюсь найти обходный путь, например пусть этот TMediPlayer проиграет видео на экране, а мой код будет копипастить каждый кадр, например через Screen (правда я не нашёл у объекта Screen свойство Canvas). Пока нужно только преобразовать моё видео в формат который этот TMediaPlayer прочитает.
Не получится. Оно все в оверлее. Сразу в видеопамять пишется. Нет там битмапов.
K>Может TMediaPlayer показать отдельный кадр из видео (застывший)?
Может. Но ты его не захватишь. Ты бы покурил что по теме для начала. Вроде все уже 100 раз описано и рассказано.
Здравствуйте, MikePetrichenko, Вы писали:
MP>Здравствуйте, Khimik, Вы писали:
MP>>>Так просто не получится. Придется в любом случае курить DirectX и через него хватать кадры видео при проигрывании. Более того, кадры, которые ты получишь будут не BMP а чем угодно (зависит от кодека) и, скорее всего не в RGB пространстве (его тоже придется преобразовывать). Ищи библиотеку под DirectX для начала.
K>>Мне сейчас надо сосредоточиться только на алгоритмах, поэтому я постараюсь найти обходный путь, например пусть этот TMediPlayer проиграет видео на экране, а мой код будет копипастить каждый кадр, например через Screen (правда я не нашёл у объекта Screen свойство Canvas). Пока нужно только преобразовать моё видео в формат который этот TMediaPlayer прочитает.
MP>Не получится. Оно все в оверлее. Сразу в видеопамять пишется. Нет там битмапов.
Причём здесь видеопамять? А если я жму PrintScreen? Мне же надо просто возвратить изображение с экрана в свой массив.
"Ты должен сделать добро из зла, потому что его больше не из чего сделать." Р.П. Уоррен
K>Причём здесь видеопамять? А если я жму PrintScreen? Мне же надо просто возвратить изображение с экрана в свой массив.
Зачем вообще тогда использовать этот медиа плейер?
Конвертируй видео в bmp'хи тем же ffmpeg'ом, да обрабатывай их.
А то как-то через жопу все получается.
Здравствуйте, vsb, Вы писали:
vsb>Можешь перекодировать в формат motion jpeg. Насколько я понимаю, это тупо последовательность кадров в jpeg формате, парсить должно быть несложно.
Я сконвертировал своё видео в .mjpeg, но лучше пока не стало — ничем этот файл не открывается, парсера ,jpeg в Delphi сходу не нашёл.
"Ты должен сделать добро из зла, потому что его больше не из чего сделать." Р.П. Уоррен
Здравствуйте, Khimik, Вы писали:
K>Причём здесь видеопамять? А если я жму PrintScreen? Мне же надо просто возвратить изображение с экрана в свой массив.
Тебе уже кучу вариантов насоветовали. Как прямых (нормальных), так и через одно место. Или тебе нужно готовое решение? Тогда озвучь сумму, которые ты готов потратить. Подумаем.
K>Здравствуйте, Khimik, Вы писали:
K>Я начал писать программу для математической обработки видео (на Delphi). K>Мне пока нужно только написать алгоритм обработки, поэтому я не буду сосредотачиваться на подключении кодеков, мне нужно просто получить формат видео файла который мой проект с TMediaPlayer сможет прочесть, так чтобы я имел bitmap-изображение для каждого кадра.
Можно просто нагенерить тестовых битмапов, сложить их в папку и гонять обработку, а потом прикрутить к этому нормальный плеер (libVLC или FFmpeg)
eсли собираетесь делать мат.обработку видео то лучше сразу в сторону OpenCV смотреть
K>Заодно у меня вопросы по формату видео файлов и сжатию: K>1) Количество кадров в секунду для всех форматов одно и то же?
во всех современных форматах (mkv, mp4,...) кадровая частота может меняться https://en.wikipedia.org/wiki/Comparison_of_video_container_formats (см. Variable frame rate)
K>2) Сжатие видео основывается на использовании предыдущего кадра как источника информации о следующем кадре? Хотелось бы примерно представлять “философскую суть” этого сжатия.
Здравствуйте, Khimik, Вы писали:
K>Я начал писать программу для математической обработки видео (на Delphi). Пока мне нужно сосредоточиться на алгоритме
Как вариант, возьми софтину для видеоредактирования и пиши свои алгоритмы в виде плагина к ней. VirtualDub выше упоминали, но я бы взял что-то более серьезное, хотя, может, тебя и VideoDub удовлетворит. Очень многие видеоэффекты разрабатывать в подобном софте комфортно т.к. ты не паришься с форматом видео, с UI, в твоем распоряжении все готовые функции редактора, с помощью которых ты можешь составлять исследовательские/вспомогательные графы обработки, представлять кадр в нужном тебе формате.
Здравствуйте, goto, Вы писали:
G>Как вариант, возьми софтину для видеоредактирования и пиши свои алгоритмы в виде плагина к ней. VirtualDub выше упоминали
Там все на С++ завязано, а топикстартер лишь в Дельфи умеет.
G> но я бы взял что-то более серьезное
Более серьезное потребует несколько недель, чтобы разобраться как там что-то сделать. И тоже все очень С++. Я делал плагины для After Effects, Premiere Pro, а также OFX, это тот еще адок.
MP>Тебе уже кучу вариантов насоветовали. Как прямых (нормальных), так и через одно место. Или тебе нужно готовое решение?
Мне хочется найти самый простой вариант. Сейчас я вижу самый простой вариант таким: если я смогу перевести своё видео в формат, который сможет проиграть мой MediaPlayer, и далее я хотя бы через какую-то копипасту извлеку битмап для каждого кадра (вроде кнопки Printscreen).
"Ты должен сделать добро из зла, потому что его больше не из чего сделать." Р.П. Уоррен
Здравствуйте, Khimik, Вы писали:
vsb>>Можешь перекодировать в формат motion jpeg. Насколько я понимаю, это тупо последовательность кадров в jpeg формате, парсить должно быть несложно.
K>Я сконвертировал своё видео в .mjpeg, но лучше пока не стало — ничем этот файл не открывается, парсера ,jpeg в Delphi сходу не нашёл.
Судя по интернету фрейм начинается байтами ff d8 и заканчиваются байтами ff d9. Всё что между ними это jpeg. Парсить с помощью TJpegImage.
Здравствуйте, D. Mon, Вы писали:
DM>Там все на С++ завязано, а топикстартер лишь в Дельфи умеет.
Тогда ква. Хотя, плагин — это часто "плоская" dll, теоретически можно склепать и на Дельфи. Но да, подходящее, без внедренного плюсового апи, надо еще найти.
Еще есть видеоредактор в Блендер, почти наверняка с возможностью кодить на Питоне.
DM>Более серьезное потребует несколько недель, чтобы разобраться как там что-то сделать. И тоже все очень С++. Я делал плагины для After Effects, Premiere Pro, а также OFX, это тот еще адок.
Многие современные видеоредакоры просты, разобраться можно за час. Но с api и Дельфи могут быть проблемы, конечно.
OFX я только баловался (конкретно с редактором Natron, который под OpenFX заточен исходно), не припомню ужасов. В After Effects тоже не припомню ада, хотя сам софт изначально имел кривейшую архитектуру. Но это происходило очень давно. Еще писал в 90-х под граф. станции SGI под пару видеоредакторов. Тоже не припомню проблем. Есть доки, примеры, все понять можно очень быстро.
alexander_r выше дал ТС наилучший совет — работать с отдельными битмапами. Разложить видео VirtualDub'ом на отдельные кадры (Export->Image sequence), и их обрабатывать. Потом им же собрать в видео, если нужно.
Здравствуйте, Khimik, Вы писали:
K>Мне хочется найти самый простой вариант. Сейчас я вижу самый простой вариант таким: если я смогу перевести своё видео в формат, который сможет проиграть мой MediaPlayer, и далее я хотя бы через какую-то копипасту извлеку битмап для каждого кадра (вроде кнопки Printscreen).
Самый простой вариант — конверти сразу в BMP Video несжатое. Вот тогда получишь то, что нужно. Чуть сложнее — заюзать что-то готовое: https://torry.net/quicksearchd.php?String=video+capture&Title=Yes
Еще сложнее — что-то почитать и заюзать DirectX (там всего-то нужно граф построить и воткнуть SampleCapture между VideoDecoder и VideoRenderer). Есть и готовые библиотеки — гугл бы уже миллион раз помог, если бы ты послушал сразу и забил на так любимый MediaPlayer. Собственно лет 100 назад, когда мне потребовалось что-то аналогичное (нужно было захват делать с хитрой железяки и в реал-тайме процессить кадры) разобрался с DirectShow (а это собственно оно) за буквально пару дней. И да, тогда с интернетами было куда как хуже. Ну еще пару дней на цветовые пространства.