【golang音频库】发现了一个特别棒的音频库,beep,使用docker方式驱动设备,可以使用golang进行控制音频设备,播放音乐。

这篇具有很好参考价值的文章主要介绍了【golang音频库】发现了一个特别棒的音频库,beep,使用docker方式驱动设备,可以使用golang进行控制音频设备,播放音乐。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言


本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/108971807

未经博主允许不得转载。
博主CSDN地址是:https://blog.csdn.net/freewebsys
博主掘金地址是:https://juejin.cn/user/585379920479288
博主知乎地址是:https://www.zhihu.com/people/freewebsystem

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

【golang音频库】发现了一个特别棒的音频库,beep,使用docker方式驱动设备,可以使用golang进行控制音频设备,播放音乐。文章来源地址https://www.toymoban.com/news/detail-406364.html

到了这里,关于【golang音频库】发现了一个特别棒的音频库,beep,使用docker方式驱动设备,可以使用golang进行控制音频设备,播放音乐。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java基础教程】特别篇:面向对象合辑——掀开Java 的面向对象盖章时代,一起来发现OOP的编程秘密!~

    面向对象编程(Object-Oriented Programming, OOP)是一种广泛应用于软件开发的编程范式 。Java是一种面向对象的编程语言,它提供了丰富的工具和特性来支持面向对象编程。本文将详细介绍Java面向对象的全部知识。 我们可以把一个Java类想象成是一个蓝图或者模具,用来创建对象。就

    2024年02月17日
    浏览(31)
  • 发现一个好玩的东西:Markdown 使用 Emoji 表情

    有两种方法可以将表情符号添加到Markdown文件中: 将表情符号复制并粘贴到Markdown格式的文本中 或者键入emoji shortcodes。 在大多数情况下,您可以简单地从Emojipedia等来源复制表情符号并将其粘贴到文档中。许多Markdown应用程序会自动以Markdown格式的文本显示表情符号。从Markd

    2024年02月06日
    浏览(26)
  • pyspark 使用udf 进行预测,发现只起了一个计算节点

    PySpark UDF 只使用一个计算节点的问题 原因分析 默认的并行度设置 PySpark在执行UDF(用户定义函数)时,默认可能不会利用所有可用的计算节点。这是因为UDF通常在单个节点上执行,并且如果没有正确设置分区,可能会导致数据倾斜或不平衡的分布。 数据分区不足 如果你的数

    2024年02月01日
    浏览(38)
  • 工作记录----CountDownLatch(特别好用的一个工具类)

    CountDownLatch 是 Java 并发包中的一个同步工具类,它可以让一个或多个线程等待其他线程完成操作。它的核心思想是,一个线程(或多个线程)在执行某个任务时,可以通过它等待其他线程的信号,直到其他线程的任务完成才继续执行。用于实现线程间的等待和通知机制。 主要

    2024年02月03日
    浏览(26)
  • golang云原生项目之:etcd服务注册与发现

    1直接调包 kitex-contrib: 上面有实现的案例,直接cv。下面是具体的理解 2 相关概念 EtcdResolver: etcd resolver是一种DNS解析器,用于将域名转换为etcd集群中的具体地址,以便应用程序可以与etcd集群进行通信。etcd是一个分布式键值存储系统,常用于服务发现、配置共享和分布式锁等

    2024年02月11日
    浏览(30)
  • 发现一个可以免费使用Midjourney机器人的方法,手机电脑都可以用!亲测有效!...

    菜鸟学Python 第 627 篇原创 AI绘画目前Midjourney算是江湖兵器排行榜翘楚,说是屠龙刀不为过!画质非常细腻,漂亮,而且功能非常强大。只要你会合适的prompt语言,可以堪比顶级插画师。但是目前Midjourney是收费的,免费的额度已经没有了,一张都没有了。大家打开官网可以看

    2024年02月11日
    浏览(31)
  • 鸿运应用开发学习-发现了一个TextInput组件中使用正则表达式后出现的BUG

    一、起因 最近我正在学习鸿蒙应用开发,准备把之前在安卓系统上开发的一个小应用,使用ArkTs语言,再写一遍,做成原生鸿蒙应用。我的应用需要对液体的体积数据进行换算,对输入的体积和对应的温度参数根据相关的计算公式进行换算,得到该液体在20℃下的标准体积,

    2024年01月16日
    浏览(50)
  • 【Docker】golang使用DockerFile正确食用指南

    大家好 我是寸铁👊 总结了一篇golang使用DockerFile正确食用指南✨ 喜欢的小伙伴可以点点关注 💝 今天寸铁想让编写好的 go 程序在 docker 上面跑,要想实现这样的效果,就需要用到今天的主角: Docker File ,那怎么使用 DockerFile 呢? 那具体怎么做呢?其实很简单,不过网上的博

    2024年03月12日
    浏览(47)
  • 使用 Golang 和 Docker 实现 Python 计算服务

    本篇文章,我们继续前一篇的话题《使用 Golang 和 Docker 运行 Python 代码》,聊聊如何使用 Golang 和 Docker 将普通的 Python 软件包封装为高性能的服务。 在上一篇内容中,我们提到过 Python 在 Golang 中运行,存在一些使用场景限制。 如果我们在整个项目中直接引入这个方案,会让

    2024年02月17日
    浏览(32)
  • 【云计算】Docker特别版——前端一篇学会

    前言: Docker 通过虚拟化安装和运行应用程序的操作系统来简化构建、运 行、管理和分发应用程序的过程。 目的是使应用程序在不同的系统环 境中高效工作。 (一)Windows桌面应用安装 下载安装包 官网:https://www.docker.com/ 安装Docker 点击安装包,自动安装 成功安装,重新启

    2024年02月11日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包