LINUX.ORG.RU

ffmpeg: Создание видео файла и передача по сети


0

1

Задача такая: скринить рабочий стол, создавать из этих скринов видео и сразу же отправлять по инету, при получение видео воспроизводить.

На данный момент видео не передается, только создается и записывается на винт. Проблема в том, что я никак не могу найти подходящего api для записи видео не на винт, а в память, откуда я смогу извлечь только что добавленный фрейм и пустить по просторам интернета.

Есть какой то способ заставить av_write_frame() писать в память? Или есть какие то другие варианты? Вроде ffmpeg поддерживает работы с сетью, но ничего похожего на av_отправить_кусок_видео_по_инету() я не нашел)

Заранее благодарю за помощь)

Посмотрел как это было сделано у меня, это адский ппц. Короче, писал кастомный сериализатор для структур типа AVCodecContext, AVStream итп через libtpl. Даже показывать не буду, на это нельзя смотреть.

Кстати, а чем не угодили обычные средства вещания на просторы инета? На gstreamer даже писать ничего не надо, достаточно погуглить за волшебным снипетом.

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

Был выбор между vlc и ffmpeg, но беглым просмотром vlc api я не нашел функционала создания видео из скринов и поэтому использовал ffmpeg.

Сериализовать ничего не надо. av_write_trailer() записывает 432 байта (во всяком случае при использовании webm), есть передать эти 432 байта по сети, потом получить эти данные, записать на диск как файл, открыть и попробовать av_dump_format(), то мы получим всю необходимую о этом видео (размер кадра, частоту, кодек и все остальное), т.е. можно, я думаю, на стороне получателя работать с этим видео более менее «просто». Логично предположить, что если заменить av_write_frame() на аналогичную функцию, но которая будет писать в память, можно будет эти данные отправить, потом получить и воспроизвести. Единственная сложность - в отправке данных.

Все это можно сделать просто выдергивая напрямую информацию из файла, но это слишком дорого. Поэтому и надо писать в память.

Надо все таки попробовать передавать кусками файл, просто для проверки моего предположения. Но в энтерпрайзе использовать это будет глупо

А что там с vlc?)

dakuenjery ()
Ответ на: комментарий от dakuenjery

если заменить av_write_frame() на аналогичную функцию

мне об этом, увы, ничего не известно. Но я достаточно давно всем этим занимался...

А что там с vlc?)

Ну, с десктопа он из коробки умеет захватывать. В сеть вещать тоже. Должно работать :)

А почему не gstreamer? Если пугает кривизна так и ffmpeg написан весьма своеобразно.

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

Дело в том, что этот код будет использоваться в другом проекте. Там свой протокол и gstreamer я думаю будет не лучшим выбором, тем более для кросс-платформенного приложения.

Можно пример кода захвата экрана с использованием libvlc?

dakuenjery ()
Ответ на: комментарий от dakuenjery

Чем не подходит ffserver & ffmpeg ? ffmpeg умеет захватывать экран и feed-ть поток в ffserver, а тот буферизирует и отдает в сеть.

vel ★★★★★ ()

а в stdout оно же может писать? Вот перенаправляй вывод в свою программу и кидай в сеть.

Harald ★★★★★ ()
Ответ на: комментарий от Harald

В stdout писать не умеет. Нужно передавать строку с именем файла. Сишный FILE не жует.

Сделал вывод в файл, потом выдираю записанный кусок из этого файла и передаю. При приеме воссоздаю это файл. Все работает, но подобная работа с винтом меня не радует

dakuenjery ()
Ответ на: комментарий от dakuenjery

тогда можно Unix сокет или пайп открывать в своей программе и передавать его ffmpeg в качестве имени выходного файла

Harald ★★★★★ ()
Ответ на: комментарий от Harald

Да. Была уже такая мысль. Но я все же надеюсь ffmpeg имеет какой то способ писать в память при помощи более адекватных методов. Все равно надо решить еще одну проблему - скриншоты. Сейчас приходится переделывать QPixmap в QImage. Это сильно нагружает проц. Наверно даже больше, чем работа с диском. Скорее всего придется использовать нативные средства и скриншотить с помощью x11api, winapi и т.д.

dakuenjery ()
Ответ на: комментарий от dakuenjery

передавать кусками файл [...] глупо

Ну почему же? Достаточно взглянуть на Apple MP4 стриминг, где они передают нарезанное видео. Очень часто это законченные 1-GOP MP4 файлы.

Так же можно писать в AVI и передавать это в сеть вместо файла. Нужно только модифицировать ffmpeg чтоб он не записывал trailer при закрытии файла. Всю необходимую для декодирования информацию AVI содержит в заголовке. При закрытии просто дописываются индексы, а в заголовке проставляет длительности дорожек.

ono ()
Ответ на: комментарий от ono

Трейлер я и так не записываю)

Ну, тогда одной проблемой меньше. Увеличу скорость создания скриншота - и все готово)

dakuenjery ()

Мне кажется, ты очень-очень странный. Фрейм и так уже лежит в памяти. Посмотри хотя бы описание структуры AVPacket. Чтобы пустить его по просторам инета, используй какой-нибудь готовый протокол передачи видео или пиши свой, если планируешь воспроизводить только своим самописным клиентом. В протоколе должны будут быть указаны данные о потоке, об этом позаботишься сам, и закодированные фреймы видео. Доступ к ним получишь через эту структуру.

auto12884835 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.