You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从MP3文件中获取声道数?使用go-mp3库未果

获取MP3声道数的可行方案

针对github.com/hajimehoshi/go-mp3库没有直接获取声道数API的问题,这里提供两种实用解决办法:

办法一:手动解析MP3帧头

MP3的声道信息存储在音频帧的帧头里,我们可以跳过开头的ID3标签后,读取第一个帧头解析出声道数:

package main

import (
	"os"
	"github.com/hajimehoshi/go-mp3"
)

func getMP3Channels(f *os.File) (int, error) {
	// 检查并跳过ID3v2标签
	f.Seek(0, 0)
	var id3Buf [10]byte
	if _, err := f.Read(id3Buf[:]); err != nil {
		return 0, err
	}

	if string(id3Buf[:3]) == "ID3" {
		// 计算ID3标签的总大小(同步安全整数格式)
		size := int(id3Buf[6])<<21 | int(id3Buf[7])<<14 | int(id3Buf[8])<<7 | int(id3Buf[9])
		if _, err := f.Seek(int64(10+size), 0); err != nil {
			return 0, err
		}
	}

	// 读取帧头前4字节
	var frameBuf [4]byte
	if _, err := f.Read(frameBuf[:]); err != nil {
		return 0, err
	}

	// 解析帧头中的声道模式位
	channelFlag := (frameBuf[1] >> 3) & 0x03
	switch channelFlag {
	case 0, 1, 2:
		return 2, nil
	case 3:
		return 1, nil
	default:
		return 0, nil
	}
}

func main() {
	file, err := os.Open("example.mp3")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	decoder, err := mp3.NewDecoder(file)
	if err != nil {
		panic(err)
	}
	defer decoder.Close()

	sampleRate := decoder.SampleRate()

	// 重新定位文件指针以解析声道数
	file.Seek(0, 0)
	numChannels, err := getMP3Channels(file)
	if err != nil {
		panic(err)
	}
}

办法二:换用支持元数据解析的音频库

如果不想手动处理帧头,可以使用go-audio/mp3库,它直接提供格式信息解析能力:

package main

import (
	"os"
	"github.com/go-audio/audio"
	"github.com/go-audio/mp3"
)

func main() {
	file, err := os.Open("example.mp3")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	decoder := mp3.NewDecoder(file)
	format := &audio.Format{}
	if err := decoder.FillFormat(format); err != nil {
		panic(err)
	}

	numChannels := format.NumChannels
	sampleRate := format.SampleRate
}

这个库会自动处理ID3标签和帧头解析,直接返回声道数、采样率等格式参数。

内容的提问来源于stack exchange,提问作者ragarac3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 13:53:08