программно изменить файл записи в directshow

#directshow #asf

#directshow #asf

Вопрос:

Я создал консольное приложение, используя directshow, которое записывает с живого источника (теперь веб-камера, затем карта захвата телевизора), добавляет текущую дату и время в overlay, а затем сохраняет аудио и видео как .asf. Теперь я хочу, чтобы выходной файл менялся каждые 60 минут без остановки графика. Я не должен терять ни секунды прямой трансляции. График выглядит примерно так:

http://imageshack.us/photo/my-images/543/graphp.jpg/

Я взглянул на GMFBridge, но у меня возникли некоторые проблемы с компиляцией их примеров. Мне интересно, есть ли способ разделить то, что существует, на фильтр наложения и источник звука, подключить их к другому устройству записи asf (приостановлено), а затем переключать их каждые 60 минут. Имя файла приостановленного фильтра asf должно измениться (pp.asf, pp2.asf, pp4.asf …). Что-то вроде этого:

http://imageshack.us/photo/my-images/546/graph1f.jpg/

с приостановкой pp1. Я нашел некоторых людей в Интернете, которые говорят, что программа записи asf удаляет текущий файл, если график не переходит в режим остановки.

Ответ №1:

Что ж, у меня есть продукт (http://www.videophill.com ) это делает именно то, что вы описали (используется для записи соответствия широковещательным требованиям) — и я обнаружил, что единственный способ сделать это — это:

  • создайте график dshow, который будет использоваться только для записи аудио и видео
  • затем, в конце графика, вставьте фильтры samplegrabber, как для аудио, так и для видео
  • затем используйте IWMWritter для создания и сохранения WMV-файла, используя образцы, извлеченные из фильтров samplegrabber
  • когда придет время, закройте один IWMWritter и создайте другой.

Таким образом, вы не потеряете ни одного кадра при переключении выходных файлов.

Конечно, также возникает вопрос о постановке в очередь и сохранении сэмплов (при переключении устройств записи) и правильном перенастройке временных меток аудио / видео, но, судя по моим исследованиям, это единственный «нормальный» способ сделать это, и я использовал его на практике.

Ответ №2:

Решение заключается в написании пользовательского фильтра DShow с двумя входными выводами в вашем случае. Один для аудиопотока, а другой для видеопотока. Внутри этого фильтра (не обязательно внутри с точки зрения архитектуры, потому что вы также можете использовать обратные вызовы, например, и выполнять работу где-то еще) вы должны создать файлы asf. При переключении файлов аудио- и видеоданные будут храниться в кэше (например, достаточно большом циклическом буфере). Вы также можете просматривать и изменять A / V синхронизацию в этом фильтре. Для записи файлов ASF я бы рекомендовал Windows Media Format SDK.
Вы также можете добавить выходные контакты, если хотите передавать аудио- и видеоданные дальше, если это необходимо для предварительного просмотра, параллельной потоковой передачи и т.д…

Ответ №3:

GMFBridge — это жизнеспособное, но сложное решение. Более прямой подход, который я реализовал в прошлом, заключается в запросе вашего ASF Writer для IWMWriterAdvanced2 интерфейса и настройке пользовательского приемника. В этом интерфейсе у вас есть методы для удаления и добавления приемников в ваш ASF writer. Автоматически подключенный приемник выполнит запись в указанный вами файл. Один из способов записать все, что вы хотите, это

1.) удалить все приемники по умолчанию:

 pWriterAdv->RemoveSink(NULL);
  

2.) зарегистрируйте пользовательский приемник:

 pWriterAdv->AddSink((IWMWriterSink*)amp;streamSink);
  

Пользовательский приемник может быть классом, который реализует IWMWriterSink , что требует реализации методов обратного вызова, которые вызываются, т.е. при записи заголовка ASF ( OnHeader(/* [in] */ INSSBuffer *pHeader); ) и при записи пакета данных ( OnDataUnit(/* [in] */ INSSBuffer *pDataUnit); ) — в вашей реализации вы можете записать их куда угодно, например, предложить дополнительные методы в этом классе, где вы можете указать имя файла, в который вы хотите записать.

Обратите внимание, что это решение не совсем подходит для того, чего вы хотите, если вам нужно записать информацию заголовка в каждом из файлов за 60 минут — после начального заголовка вы получите только данные пакета ASF. Обходным решением для этого могло бы быть перезапись начального заголовка перед любыми пакетными данными каждого файла, однако это приведет к созданию неиндексированного (недоступного для поиска) файла ASF.