这个项目能做什么
Oto(v3)是一个用于播放声音的底层 Go 库。它的设计目标是贴近音频硬件,将解码和更高层的音频处理留给调用方。
平台
Oto 支持 Windows、macOS、Linux、FreeBSD 和 OpenBSD,且无需 Cgo。它还列出了 Android、iOS、WebAssembly(无需 Cgo)、Nintendo Switch 和 Xbox 作为支持的目标平台。在某些平台上,Go 需要使用路径中可用的 C/C++ 编译器;主机平台目标可能仍需要可用的 C/C++ 工具链。
平台说明
在 macOS 上,需要 AudioToolbox.framework,但会自动链接。在 iOS 上,必须将 AVFoundation.framework 和 AudioToolbox.framework 添加到 Xcode 项目的链接框架中。在 Linux 和 BSD 上,Oto 通过纯 Go 包 github.com/jfreymuth/pulse 使用 PulseAudio;如果无法发现 PulseAudio 服务器,可以设置 PULSE_SERVER 环境变量。当无法连接到 PulseAudio 服务器时,Oto 会回退到 ALSA,这同样不需要 Cgo:libasound.so.2 在运行时动态加载,因此构建时不需要 ALSA 开发头文件,但运行时必须存在该共享库。在 FreeBSD 上,使用 CGO_ENABLED=0 构建时,还需要为 purego fakecgo 包设置特定的 gcflags,而启用 Cgo 的原生构建则不需要额外设置。
核心概念
两个主要组件是 Context 和 Player。Context 处理与操作系统和音频驱动的交互,每个程序只能有一个 context。通过 context 可以创建任意数量的 Player,每个 Player 都接收一个 io.Reader,并从中读取表示声音的字节。单个 io.Reader 不得由多个 player 共享。
用法
创建 Context 使用 oto.NewContextOptions,其字段包括 SampleRate(通常为 44100 或 48000)、ChannelCount(1 表示单声道,2 表示立体声)和 Format(例如 oto.FormatSignedInt16LE)。oto.NewContext 返回 context、一个 ready channel 和一个 error;调用方在使用前等待 ready channel,然后检查 context 的错误。Player 通过 otoCtx.NewPlayer(reader) 创建,初始为暂停状态,Play() 是异步的。可以轮询 IsPlaying() 来等待播放完成,Seek() 允许在声音中重新定位。
可以通过将文件读入字节切片并用 bytes.Reader 包装来从内存播放声音,也可以通过将 *os.File 直接传给解码器来进行流式播放。流式播放时,必须保持文件对象存活,并且在播放完成前不要关闭它,否则播放可能会产生杂音。
高级用法
Player 维护一个内部音频数据缓冲区,因此从 io.Reader 读取的字节不一定已经被音频设备播放。数据从 io.Reader 移动到内部缓冲区,然后移动到音频设备,第二步的时机没有保证,因此可能会有轻微延迟。Player.BufferedSize() 报告已缓冲的数据量,SetBufferSize() 调整底层缓冲区大小。NewPlayer 返回一个 *oto.Player,其方法包括 SetBufferSize 和 Seek。
交叉编译
交叉编译到 macOS、Windows、Linux 或 BSD,可以通过将 GOOS 设置为 darwin、windows、linux 或相应的 BSD 变体来完成。对于其他平台,必须安装目标架构库,并且必须设置 CGO_ENABLED=1,因为 Go 在交叉编译时默认禁用 Cgo。
评论
0 人表达喜爱 · 满10人后显示 Deer Point
登录后参与讨论。