![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
VCL.TMediaPlayer. Проблема записи при невыбранном файлеDelphi , Мультимедиа , Запись звукаVCL.TMediaPlayer. Проблема записи при невыбранном файлеАвтор: Кирилл Грибунин Проблема выявлена в Delphi 6, UpdatePack 2, под управлением Windows 2000, Windows ME, Windows 98. Нужно записать что-то, например, с микрофона, после чего сохранить это в файл, например test.wav. Что для этого делаем. Так как файла на момент начала записи ещё нет, оставляем свойство FileName пустым. Свойство DeviceType ставим dtWaveAudio, т.к. при dtAutoSelect получим при открытии exсeption с сообщением, что невозможно определить тип устройства из расширения файла. Далее пишем следующий код:
Запись не начинается. Отладка функции StartRecording показывает, что последняя строка этой функции:
возвращает код 274 (MCIERR_UNSUPPORTED_FUNCTION). Изучение проблемы показывает следующее. В методе Open написан следующий код:
т.е., если DeviceType не dtAutoSelect, то флаг MCI_OPEN_ELEMENT не ставится. Этот код, видимо был написан после прочтения следующего места в MSDN: To use automatic type selection (via the entries in the registry), assign the filename and file extension to the lpstrElementName member of the structure identified by lpOpen, set the lpstrDeviceType member to NULL, and set the MCI_OPEN_ELEMENT flag. Но программист MPlayer.pas не прочитал другого места в MSDN, в котором описывается ещё одно применение флага MCI_OPEN_ELEMENT: If a compound device supports recording, an application can open the device without specifying a name for the device element. In this case, the application uses the MCI_OPEN_ELEMENT flag with a zero-length, zero-terminated string for the element name. Recorded data is not saved in a permanent file until the application explicitly saves it with the MCI_SAVE command, specifying the name of the destination file. ТИПОВЫЕ РЕШЕНИЯ Видимо, ситуация следующая. В MSDN указывается, что флаг MCI_OPEN_ELEMENT следует использовать не во всех случаях, а в двух ситуациях:
Таким образом, уже при открытии нужно знать, что мы собираемся дальше делать с устройством. Так как в логике MediaPlayer в методе Open этого нам знать не дано, то можно попытаться в коде этого метода сделать предположения:
Код этого участка получается следующим:
С таким исправлением тестовый пример работает нормально. Надеюсь, что вышеприведённый код, хотя и не особенно корректный (в силу некорректных предположений о дальнейшем использовании устройства при открытии), но как-то может помочь программистам, пытающимся использовать MediaPlayer для записи хоть каким-нибудь образом. P.S. Код MPlayer.pas вообще довольно неряшлив. Например, в том же методе Open видим следующий фрагмент, в котором два раза проверяется условие FDeviceType <> dtAutoSelect, первый раз — вхолостую:
Скачать тест StoneTest_38.zip (12k) КОММЕНТАРИЙ В MPlayer.pas от Delphi 5 Update pack 1 это место имеет другой вид (кстати, это единственное отличие в коде модуля от версии Delphi 6):
Но, тем не менее, описанная проблема имеет место быть. Приведенный автором код работает не во всех случаях (проверено в Delphi 5, WinNT4 SP6). А именно: нельзя записать в существующий файл WAV и нельзя открыть устройство для воспроизведения без указания файла (например - CDAudio как диск). Эксперимент показывает, что для успешной операции записи звука в файл (новый или существующий), при явном указании типа устройства, должны быть установлены оба флага - MCI_OPEN_TYPE и MCI_OPEN_ELEMENT. Исправленный для этого случая код выглядит следующим образом:
Однако, при этом TMediaPlayer может не работать с другими типами устройств. Проверка показала, что так оно и есть - пишутся и проигрываются WAV файлы нормально, AVI - тоже проигрывается, а вот устройство CDAudio даже открываться не хочет - Exception на основании ошибки 296 (MCIERR_INVALID_FILE). Остальные типы устройств не проверялись. Заранее нельзя определить, открывают TMediaPlayer для записи или нет. Напрашивается мысль, что MCI_OPEN_ELEMENT в случае FDeviceType <> dtAutoSelect можно выставлять только при условии, если устройство поддерживает запись. Об этом можно узнать из флага FCanRecord, значение которого определяется в методе
Но эта процедура вызывается (и может быть вызвана) только после открытия устройства. Получается замкнутый круг. Вывод. Исходный код TMediaPlayer нуждается в серьезной доработке. Как "заплатный" вариант, представляется попытка открыть устройство с MCI_OPEN_ELEMENT, а в случае ошибки - сбросить флаг и повторить попытку:
В статье описана проблема записи звука с помощью TMediaPlayer в Delphi 6, UpdatePack 2, под управлением Windows 2000, Windows ME, Windows 98, при не выбранном файле для записи. Комментарии и вопросыПолучайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: Запись звука ::
|
|||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |