Discord をクローンしようとしていたところ、オーディオに ogg 形式が使用されていることがわかりました (おそらく)。データベースに保存するオーディオの長さを取得しようとしています。
OGG オーディオの長さの取得に関する stackoverflow ソリューションは、興味深いと思いました。このアプローチには、ファイルの最後までシークし、最後の Ogg ページ ヘッダーを見つけて、そのグラニュールの位置を読み取ることが含まれます。
func getOggDurationMs(reader io.Reader) (int64, error) { // Read the entire Ogg file into a byte slice data, err := io.ReadAll(reader) if err != nil { return 0, fmt.Errorf("error reading Ogg file: %w", err) } // Search for the "OggS" signature and calculate the length var length int64 for i := len(data) - 14; i >= 0 && length == 0; i-- { if data[i] == 'O' && data[i+1] == 'g' && data[i+2] == 'g' && data[i+3] == 'S' { length = int64(readLittleEndianInt(data[i+6 : i+14])) } } // Search for the "vorbis" signature and calculate the rate var rate int64 for i := 0; i < len(data)-14 && rate == 0; i++ { if data[i] == 'v' && data[i+1] == 'o' && data[i+2] == 'r' && data[i+3] == 'b' && data[i+4] == 'i' && data[i+5] == 's' { rate = int64(readLittleEndianInt(data[i+11 : i+15])) } } if length == 0 || rate == 0 { return 0, fmt.Errorf("could not find necessary information in Ogg file") } durationMs := length * 1000 / rate return durationMs, nil } func readLittleEndianInt(data []byte) int64 { return int64(uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16 | uint32(data[3])<<24) }
ここで共有することにしました。実装が非常に素晴らしいと思ったので、他の人にも役立つかもしれません
以上がGo での Ogg オーディオの長さの計算: ステップバイステップ ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。