2008-08-30 6 views
18

Есть ли переносимый, не ограниченный патентом способ воспроизведения сжатых звуковых файлов в C#/.Net? Я хочу играть короткие звуки «звон» в различных событиях, происходящих в программе.Как можно воспроизводить сжатые звуковые файлы на C# портативным способом?

System.Media.SoundPlayer может обрабатывать только WAV, но обычно они являются большими для встраивания в загружаемое приложение. MP3 защищен патентами, поэтому даже если бы был полностью управляемый декодер/плеер, он не был бы свободно перераспределять. Лучшим доступным форматом будет OGG Vorbis, но мне не повезло работать с библиотеками C# Vorbis (мне удалось извлечь необработанную PCM с помощью csvorbis, но я не знаю, как играть в нее потом).

Я не хочу распространять никакие файлы с моим приложением и не зависеть от P/Invoke, так как проект должен работать как минимум на Windows и Linux. Я в порядке с комплектами .Net, если они совместимы с лицензиями GPL.

[этот вопрос является продолжением к списку в mailing list discussion on mono-dev рассылки год назад]

ответ

6

я, наконец, вернулся к этой теме, и, используя помощь BrokenGlass on writing WAVE header, обновленные csvorbis. Я добавил OggDecodeStream, который можно передать System.Media.SoundPlayer, чтобы просто воспроизвести любой (совместимый) поток Ogg Vorbis. Пример использования:

using (var file = new FileStream(oggFilename, FileMode.Open, FileAccess.Read)) 
{ 
    var player = new SoundPlayer(new OggDecodeStream(file)); 
    player.PlaySync(); 
} 

«Совместимый» в этом случае означает, что «это сработало, когда я попробовал». Декодер полностью управляется, отлично работает на Microsoft .Net - на данный момент, как представляется, в Mono наблюдается регрессия, которая вызывает искажение.

Устаревшие:

System.Diagnostics.Process.Start("fullPath.mp3");

Я удивлен, но method Dinah mentioned на самом деле работает. Тем не менее, я думал о том, чтобы играть короткие звуки «звонка» в различных событиях, происходящих в программе, я не хочу запускать медиа-плеер пользователя каждый раз, когда мне нужно сделать «пинг!». звук.

Что касается ссылки на проект кода - это, к сожалению, только оболочка P/Invoke.

+0

Я предполагаю, что это будет работать * только *, если у пользователя установлен MP3-плеер, правильно? – 2008-09-06 20:14:30

+0

Это будет «работать», запустив приложение по умолчанию для расширения MP3, если оно определено на компьютере. Я не знаю ответа (или я бы ответил на него), но я постараюсь найти лучший способ, особенно * если интероперабельность - это ваша цель. – 2008-09-24 23:40:22

+0

Вышеупомянутые комментарии больше не применяются к обновленному ответу. – skolima 2012-03-05 16:46:01

1

Вызов чего-то, что находится в 'System.Diagnostics', чтобы играть звук, выглядит для меня довольно плохой идеей. Вот то, что эта функция предназначена для:

// 
    // Summary: 
    //  Starts a process resource by specifying the name of a document or application 
    //  file and associates the resource with a new System.Diagnostics.Process component. 
    // 
    // Parameters: 
    // fileName: 
    //  The name of a document or application file to run in the process. 
    // 
    // Returns: 
    //  A new System.Diagnostics.Process component that is associated with the process 
    //  resource, or null, if no process resource is started (for example, if an 
    //  existing process is reused). 
    // 
    // Exceptions: 
    // System.ComponentModel.Win32Exception: 
    //  There was an error in opening the associated file. 
    // 
    // System.ObjectDisposedException: 
    //  The process object has already been disposed. 
    // 
    // System.IO.FileNotFoundException: 
    //  The PATH environment variable has a string containing quotes. 
2

Я ни хочу распространять любые исполняемые файлы с моим приложением, ни зависят от P/Invoke, как проект должен работать по крайней мере на Windows, и Linux , Я в порядке с набором .Net сборок, если они лицензионно совместимы с GPL.

К сожалению, его будет невозможно избежать распространения двоичных файлов или избежать P/Invoke. Библиотеки классов .net в любом случае используют P/Invoke, управляемый код должен в какой-то момент взаимодействовать с неуправляемым API операционной системы, чтобы что-то сделать.

Преобразование файла OGG в PCM должно быть возможным в управляемом коде, но из-за отсутствия встроенной поддержки аудио.сеть, вы на самом деле есть 3 варианта:

  1. Вызов внешней программы для воспроизведения звука (как предлагалось ранее)

  2. P/Invoke модуль C для воспроизведения звука

  3. P/Вызовите OS API для воспроизведения звука.

(4.) Если вы используете только этот код в окнах, возможно, вы просто используете DirectShow.

P/Invoke может использоваться в поперечном пути http://www.mono-project.com/Interop_with_Native_Libraries#Library_Names

платформы После того, как у вас есть данные PCM (с использованием OGG C Lib или управляемый код, что-то вроде этого http://www.robburke.net/mle/mp3sharp/, конечно, есть вопросы лицензирования с MP3) , вам понадобится способ воспроизвести его, к сожалению, .net не дает никакой прямой оценки вашей звуковой карты или методов воспроизведения потокового аудио. Вы можете преобразовать файлы ogg в PCM при запуске, а затем использовать System.Media.SoundPlayer для воспроизведения созданных wav-файлов. В текущем методе Microsoft предлагает использовать P/Invoke для доступа к API воспроизведения звука в ОС http://msdn.microsoft.com/en-us/library/ms229685.aspx

API кросс-платформы для воспроизведения звука PCM - это OpenAL, и вы должны иметь возможность воспроизведения звука (PCM) с использованием привязок C# для OpenAL при www.taoframework.com, вам, к сожалению, нужно будет скопировать несколько файлов DLL и .so с вашим приложением, чтобы оно работало при распространении, но это, как я уже объяснял ранее, неизбежно.

0

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

Использование System.Diagnostic запустит внешнее программное обеспечение, и я сомневаюсь, что вы этого хотите, не так ли? Вы просто хотите, чтобы звуковой файл X воспроизводился в фоновом режиме, когда Y происходит в вашей программе, не так ли?

Отрицательный, потому что это выглядит как интересный вопрос. : D

0

API-XNA Аудио хорошо работают в .net/C# приложений и прекрасно работать для этого приложения. Триггер, основанный на событиях, наряду с последовательным воспроизведением нескольких звуков. Именно то, что вы хотите. О, и сжатие.

+1

Это не переносимо, XNA не поддерживается в Mono, и порт в основном мертв: http://www.monoxna.org/node/4 – skolima 2010-05-21 07:42:20

0

Ну, это зависит от законов, связанных с патентами в данной стране, но нет никакого способа написать mp3-декодер, не нарушая патентов, насколько я знаю. Я думаю, что лучшее кросс-платформенное решение с открытым исходным кодом для вашей проблемы - GStreamer. Он имеет привязки C#, которые быстро развиваются. Однако использование и создание GStreamer в Windows - непростая задача. Here - хорошая отправная точка. Banshee Проект использует этот подход, но он пока не используется в окнах (однако есть некоторые почти работающие ночные сборки). FMOD также является хорошей альтернативой. К сожалению, это не открытый исходный код, и я обнаружил, что его API как-то C-стиле.

0

Не уверен, если это по-прежнему актуально. Самое простое решение - использовать NAudio, который является управляемым API-интерфейсом с открытым исходным кодом, написанным на C#. Другое дело - использовать ffmpeg и создать процесс до ffplay.exe (правильные двоичные файлы находятся в разделяемых сборках).