以下の記事ではASC(Audio Specific Config)をffprobeで取り出したが、これはmp4デマルチプレクサでも取り出すことができる。
今回はabema/go-mp4を使ってやってみる。
mp4の仕様によればesdsというboxの中に入っているらしいので、それを取り出せばいい。
// esdsからASCの値を含むデスクリプタを取り出す func getASCDescriptor(reader io.ReadSeeker) (*mp4.Descriptor, error) { var ascDescriptor *mp4.Descriptor if results, err := mp4.ExtractBoxWithPayload(reader, nil, mp4.BoxPath{ mp4.BoxTypeMoov(), mp4.BoxTypeTrak(), mp4.BoxTypeMdia(), mp4.BoxTypeMinf(), mp4.BoxTypeStbl(), mp4.BoxTypeStsd(), mp4.BoxTypeMp4a(), mp4.BoxTypeEsds(), }); err != nil { return nil, err } else { esds := results[0].Payload.(*mp4.Esds) for _, descriptor := range esds.Descriptors { if descriptor.Tag == mp4.DecSpecificInfoTag { ascDescriptor = &descriptor break } } if ascDescriptor == nil { return nil, errors.New("no descriptor found") } } return ascDescriptor, nil }
単なるm4aファイルに対して動かして確認してみた限り esds.Descriptors
には4つ程度のデスクリプタが含まれていた。その中で mp4.DecSepcificInfoTag
という値に該当するやつがASCを持っているっぽい。なのでそれを探してやればいい。
あとはこんな感じでgo-fdkaacの初期化のときのパラメタとして使える。
descriptor, err := getASCDescriptor(m4aFile) if err != nil { panic(err) } else if len(descriptor.Data) == 0 { panic(errors.New("no ASC available")) } decoder := fdkaac.NewAacDecoder() if err := decoder.InitRaw([]byte{ descriptor.Data[0], descriptor.Data[1], }); err != nil { panic(err) }