golang音频库发现了特别棒的音频库,beep,使用docker方式驱动设备,可以使用golang进行控制音频设备,播放音乐。
前言
本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/108971807
1,关于beep和alsa库
ALSA(Advanced Linux Sound Architecture)是linux上主流的音频结构,在没有出现ALSA架构之前,一直使用的是OSS(Open Sound System)音频架构。
其他介绍:
https://blog.csdn.net/longwang155069/article/details/53260731
beep是一个golang的开源音频库:
Decode and play WAV, MP3, OGG, and FLAC.
Encode and save WAV.
Very simple API. Limiting the support to stereo (two channel) audio made it possible to simplify the architecture and the API.
Rich library of compositors and effects. Loop, pause/resume, change volume, mix, sequence, change playback speed, and more.
Easily create new effects. With the Streamer interface, creating new effects is very easy.
Generate completely own artificial sounds. Again, the Streamer interface enables easy sound generation.
Very small codebase. The core is just ~1K LOC.
https://github.com/faiface/beep
2,使用需要pkg-config和alsa库
# 安装工具pkg
sudo apt install pkg-config
# 安装 alsa 开发库
sudo apt-get install libalsa-ocaml-dev
最简单的一个代码:
package main
import (
"log"
"os"
"time"
"github.com/faiface/beep"
"github.com/faiface/beep/mp3"
"github.com/faiface/beep/speaker"
)
func main() {
f, err := os.Open("./Lame_Drivers_-_01_-_Frozen_Egg.mp3")
if err != nil {
log.Fatal(err)
}
streamer, format, err := mp3.Decode(f)
if err != nil {
log.Fatal(err)
}
defer streamer.Close()
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
done := make(chan bool)
speaker.Play(beep.Seq(streamer, beep.Callback(func() {
done <- true
})))
<-done
}
然后就可以听到声音播放了:
go run main.go
在linux 上可以使用:
$ arecord -l
**** CAPTURE 硬體裝置清單 ****
card 1: Generic_1 [HD-Audio Generic], device 0: ALC257 Analog [ALC257 Analog]
子设备: 1/1
子设备 #0: subdevice #0
其他,要是有多个音频设备呢?咋选择呢?
https://blog.csdn.net/lihuan680680/article/details/121941653
实际上beep 依赖另外一个库:oto
https://github.com/hajimehoshi/oto
// #cgo pkg-config: alsa
//
// #include <alsa/asoundlib.h>
import "C"
import (
"fmt"
"strings"
"sync"
"unsafe"
"github.com/hajimehoshi/oto/v2/internal/mux"
)
....
抄袭了下代码,可以通过main函数和alsa库,获得全部设备信息。
// Copyright 2021 The Oto Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build !android && !darwin && !js && !windows && !nintendosdk
package main
// #cgo pkg-config: alsa
//
// #include <alsa/asoundlib.h>
import "C"
import (
"fmt"
"sync"
"unsafe"
)
type context struct {
channelCount int
suspended bool
handle *C.snd_pcm_t
cond *sync.Cond
ready chan struct{}
}
var theContext *context
func alsaError(name string, err C.int) error {
return fmt.Errorf("oto: ALSA error at %s: %s", name, C.GoString(C.snd_strerror(err)))
}
func deviceCandidates() []string {
const getAllDevices = -1
cPCMInterfaceName := C.CString("pcm")
defer C.free(unsafe.Pointer(cPCMInterfaceName))
var hints *unsafe.Pointer
err := C.snd_device_name_hint(getAllDevices, cPCMInterfaceName, &hints)
if err != 0 {
return []string{"default", "plug:default"}
}
defer C.snd_device_name_free_hint(hints)
var devices []string
cIoHintName := C.CString("IOID")
defer C.free(unsafe.Pointer(cIoHintName))
cNameHintName := C.CString("NAME")
defer C.free(unsafe.Pointer(cNameHintName))
for it := hints; *it != nil; it = (*unsafe.Pointer)(unsafe.Pointer(uintptr(unsafe.Pointer(it)) unsafe.Sizeof(uintptr(0)))) {
io := C.snd_device_name_get_hint(*it, cIoHintName)
defer func() {
if io != nil {
C.free(unsafe.Pointer(io))
}
}()
if C.GoString(io) == "Input" {
continue
}
name := C.snd_device_name_get_hint(*it, cNameHintName)
defer func() {
if name != nil {
C.free(unsafe.Pointer(name))
}
}()
if name == nil {
continue
}
goName := C.GoString(name)
if goName == "null" {
continue
}
if goName == "default" {
continue
}
devices = append(devices, goName)
}
devices = append([]string{"default", "plug:default"}, devices...)
return devices
}
func main() {
deviceList := deviceCandidates()
for idx,device := range deviceList {
println(idx)
println(device)
}
}
3,总结
可以使用golang 然后控制音频,播放音乐,也是非常不错的库,库也是非常的强大。
可以需要在linux上,调用alsa的库,然后播放音频mp3文件。
本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/108971807
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfiafeg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13