Kevin Schweikert/Go-Soundboard
Кроссплатформенная звуковая панель написана в Go и Svelte
💡 Идея
«Нужно» для этого приложения возбуждено, когда я хотел повеселиться и использовать звук для некоторых веб-конференций с друзьями и семьей. Я бегаю на Linux, и я не смог найти программное обеспечение, которое работало так, как я хотел, чтобы он работал. Поэтому я решил написать свои собственные и практиковать свои навыки в моем первом реальном проекте Go. Он должен просто вывести некоторые звуковые файлы с помощью кнопки. Тогда я мог бы использовать Audio Connection Kit
Комплект Audio подключения JACK (или JACK; рекурсивная аббревиатура) – это демон профессионального звукового сервера, который предоставляет в режиме реального времени, низкозащитные соединения для аудио- и MIDI-данных между приложениями, которые используют его API.
Википедия
Чтобы найти это на мой виртуальный вход. К счастью, это было очень легко, потому что, когда я впервые бегал, он появился как собственный клиент Джека. Поэтому мне просто пришлось подключить связь, как в следующем примере. Pulseaudio Джек раковина и Pulseaudio Jack Source Являются мой виртуальный и вывод. Они также устанавливаются в мою систему в качестве устройства и вывода устройства. Тогда я могу подключить Система (Микрофон) и alsa-jack.jackp.122733.0 (Мое приложение Soundboard) на виртуальный вход. Это также подключено к выводу моей системы, чтобы услышать сам звуки. Затем в совещании программного обеспечения я просто должен выбрать Pulseaudio Jack Source Поскольку вход микрофона и участники услышат меня, а также мои удивительные звуки!
💾 Сервер
Сервер написан в ходу. Это простой HTTP-сервер, который обслуживает веб-интерфейс и создает конечную точку WebSocket для контрольных сообщений. Я использовал пакет Звуковой сигнал Для воспроизведения аудиофайлов в папке и Горилла Websocket Для облегчения обработки Websocket.
Когда вы запускаете приложение, он ищет все файлы в указанной папке. Для этого я создал пакет под названием Аудио и некоторые структуры, чтобы удерживать необходимую информацию.
package audio
// SoundFile holds a sound struct
type SoundFile struct {
Path string `json:"path"`
Name string `json:"name"`
Extension string `json:"extension"`
ID int `json:"id"`
}
После того, как я собрал все Звуковые файлы Я создал новый Звуковой каталог Чтобы сохранить вещи более компактными и иметь ссылку на путь к файлу папки
// SoundDirectory collects all SoundFiles from a specific path
type SoundDirectory struct {
SoundFiles []SoundFile `json:"soundfiles"`
Path string `json:"path"`
}
Затем создан новый объект панели в Этот пример звуковой сигнал Но слегка модифицировано, чтобы также удерживало вновь созданное Sounddirectory и вместо стримера, который я использовал смеситель только для того, чтобы отменить один поток вместо каждого потока файлов. Чтобы узнать больше о Beep Package, посмотрите на Вики
// Panel holds all Player structs like mixer, ctrl and Volume
type Panel struct {
speakerSampleRate beep.SampleRate
mixer *beep.Mixer
ctrl *beep.Ctrl
Volume *effects.Volume
SoundDir SoundDirectory
}
// NewPanel returns a pointer to a Panel struct
func NewPanel(speakerSampleRate int, dir SoundDirectory) *Panel {
mixer := &beep.Mixer{}
ctrl := &beep.Ctrl{Streamer: mixer}
volume := &effects.Volume{Streamer: mixer, Base: 2}
return &Panel{beep.SampleRate(speakerSampleRate), mixer, ctrl, volume, dir}
}
В Главная Функция I Parse i Parse Некоторые флаги командной строки, получите все аудиофайлы из указанной папки (код не отображается в этой статье), создает новый аудио. Панель l struct и передайте это к функции handlewocket. После этого я запускаю сервер. Есть какой-то другой код для обслуживания статических файлов из веб-интерфейса, но я решил сохранить это из объема этой статьи.
// Define and parse the command line flags
folderPath := flag.String("path", "./sounds", "path to sound files")
speakerSampleRate := flag.Int("samplerate", 48000, "Output Samplerate in Hz")
buffSize := flag.Int("buff", 256, "Output buffer size in bytes")
port := flag.Int("port", 8000, "Port to listen for the webinterface")
flag.Parse()
// create a new SoundDirectory
dir, err := audio.GetFilesInFolder(*folderPath)
if err != nil {
log.Println(err)
}
// create a new Panel
ap := audio.NewPanel(*speakerSampleRate, dir)
err = ap.Init(*buffSize)
if err != nil {
log.Println(err)
}
http.HandleFunc("/websocket", handleWebSocket([OTHER ARGUMENTS], ap))
log.Printf("Server listening on 0.0.0.0:%d", *port)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
Оттуда теперь я могу отправить SoundFile Ломтик через подключение Websocket с Marshalling его в Msg структура с какой-то дополнительной информацией.
// Switch constants
const (
Load = "load"
Play = "play"
Error = "error"
Volume = "volume"
Stop = "stop"
)
// Msg struct to marshal and unmarshal the websocket json data
type Msg struct {
Type string `json:"type"`
Msg string `json:"msg"`
SoundFiles []audio.SoundFile `json:"soundfiles"`
Volume float64 `json:"volume"`
}
Как видите, я определил свой собственный протокол сообщений. Каждое сообщение должно иметь тип и с этой информацией, которую я знаю, как использовать это сообщение. Например, в оператор выключателя. Я прочитал объект JSON из соединения с C.Readjson () и поставить Тип поле в оператор выключателя. После этого я могу решить, что делать с сообщением. Например, когда Msg это Тип: Играть Я использую функцию Playsound () от моего аудио. Панель и дать ему первый файл из SoundFiles Массив (это мое решение повторно использовать SoundFiles поле несколько раз. Как массив нескольких файлов в Нагрузка команда или массив с одним элементом в Играть команда). Если есть ошибка при попытке играть SoundFile Я создаю новое сообщение с Тип: Ошибка и сам текст ошибки в поле сообщения. Это отправляется на мой интерфейс и обрабатывается с уведомлением для пользователя. Но есть больше возможностей, таких как окно сообщения с видом журнала всех сообщений об ошибках.
//c is the pointer to the websocket client connection with the type *websocket.Conn
payload := new(Msg)
err := c.ReadJSON(payload)
switch Msg.Type {
case Play:
err := ap.PlaySound(payload.SoundFiles[0])
if err != nil {
c.WriteJSON(Msg{
Type: Error,
Msg: err.Error(),
})
}
case Load:
....
.
.
.
}
✏️ UI
Потому что я понятия не имею, как построить настольный интерфейс, я решил построить веб-интерфейс с моим любимым каркасом JavaScript SVELTE Отказ Web-ui подается из моего приложения и подключается к /Websocket. Маршрут для получения всех необходимых данных, которые также обрабатываются в операторе выключателя. В более простую форму это выглядит так:
{#each sounds as sound}
{/each}
Для каждого объекта массива в звуки Svelte создаст компонент. Если массив меняется, кнопки будут динамически меняться. Кроме того, вы замечаете, что Comomponent имеет пользовательское событие На: Играть Отказ Он будет уволен, когда кнопка нажала и отправит некоторые данные с событием. В SVELTE вы можете просто создать диспетчеру событий и назвать вашему пользовательским событием, поэтому вы можете прослушать его, где бы вы ни захотите использовать компонент. Компонент Soundbutton выглядит что-то подобное:
Я знаю, что это очень базовое объяснение, как все работает, но я хочу сохранить его короткий и простой. Если есть какие-либо вопросы, я рад помочь и объяснить! Посмотрите на полный код в GitHub:
Kevin Schweikert/Go-Soundboard
Кроссплатформенная звуковая панель написана в Go и Svelte
🔧 использование
go build -o [EXECUTABLE_NAME] ./[EXECUTABLE_NAME] [FLAGS] OR go run .
Запустите серверное приложение с помощью этих возможных флагов:
-buff int
Output buffer size in bytes (default 256)
-path string
path to sound files (default "./sounds")
-port int
Port to listen for the web interface (default 8000)
-samplerate int
Output Samplerate in Hz (default 48000)
Перейти к localhost: 8000 И вы должны увидеть это:
🎊 Конец
Это мой первый пост и публичный проект, который я показываю вам. Есть еще много вещей, которые я мог бы сделать лучше Но я рад слышать ваши мысли! Мне нравится слышать ваши предложения или конструктивную критику о моем коде, идее и самой статье! Я работаю над созданием исполняемых файлов для каждой системы, поэтому для всех проще в использовании и веселиться с ним!
Ваше здоровье!
Оригинал: “https://dev.to/kevinschweikert/a-cross-plattform-soundboard-written-in-go-and-svelte-gge”