Home  >  Article  >  Backend Development  >  Calculating Ogg Audio Duration in Go: A Step-by-Step Guide

Calculating Ogg Audio Duration in Go: A Step-by-Step Guide

PHPz
PHPzOriginal
2024-09-05 21:31:09423browse

Calculating Ogg Audio Duration in Go: A Step-by-Step Guide

I was trying to clone discord and i found out they use ogg formats for audio (i think), im trying to get the audio duration to store in the database.

A stackoverflow solution about getting the OGG audio duration, i found fascinating. The approach involves seeking to the end of the file, finding the last Ogg page header, and reading its granule position.

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)
}

I decided to share it here, i just found the implementation very cool and maybe help some other people out

The above is the detailed content of Calculating Ogg Audio Duration in Go: A Step-by-Step Guide. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:Benchmark with GolangNext article:Benchmark with Golang