Рубрики
Без рубрики

Кроссплатформенная звуковая панель написана в Go и Svelte

Kevin Schweikert / Go-soundboard … Теги с Go, Svelte, JavaScript, Showdev.

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”