Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions examples/decode-webm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# decode-webm
decode-webm demonstrates decoding a webm file and saving the results to a single file

## Instructions
### Install decode-webm
Download and install the decode-webm

```
go install github.com/pion/opus/examples/decode-webm@latest
```

### Create a webm file to decode
Encode Opus into an webm file, or use one that you already have.

```
ffmpeg -i $INPUT_FILE -c:a libopus -ac 1 -b:a 64K output.webm
```

### Decode
Demux and decode the provided `webm` file. The output audio samples will be saved to disk.

```
decode-webm `pwd`/output.webm `audio-samples.pcm`
```

### Play your audio
Now play the audio with the tool of your choice.

```
gst-launch-1.0 filesrc location=audio-samples.pcm ! audio/x-raw, format=S16LE, rate=48000,channels=1 ! autoaudiosink -v
```

```
ffplay -f s16le -ar 48000 audio-samples.pcm
```
8 changes: 8 additions & 0 deletions examples/decode-webm/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/pion/opus/examples/decode-webm

go 1.24.0

require (
github.com/at-wat/ebml-go v0.18.0
github.com/pion/opus v0.1.0
)
12 changes: 12 additions & 0 deletions examples/decode-webm/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/at-wat/ebml-go v0.18.0 h1:SNkpBFR4jCQV1rI4Bm1tSuIYnusxe2qQ4GHJia9eQg4=
github.com/at-wat/ebml-go v0.18.0/go.mod h1:w1cJs7zmGsb5nnSvhWGKLCxvfu4FVx5ERvYDIalj1ww=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pion/opus v0.1.0 h1:GgK/a3DNDrffKjUFsK39rZKqfv7bQ2S2eqRKt0BnqAE=
github.com/pion/opus v0.1.0/go.mod h1:t5Xog2n682JnawoykACE6nKVmupFvmJvkpM7x6bTv6g=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
71 changes: 71 additions & 0 deletions examples/decode-webm/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-FileCopyrightText: 2026 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

// Package main is an example of an Opus decoder that from webm save the output PCM to disk
package main

import (
"os"

"github.com/at-wat/ebml-go"
"github.com/at-wat/ebml-go/webm"
"github.com/pion/opus"
)

func main() { // nolint:cyclop
if len(os.Args) != 3 {
panic("Usage: <in-file> <out-file>")
}

inputFile, err := os.Open(os.Args[1]) // #nosec G703
if err != nil {
panic(err)
}

var webmData struct {
Segment webm.Segment `ebml:"Segment"`
}

err = ebml.Unmarshal(inputFile, &webmData)
if err != nil {
panic(err)
}

var opusTrackNumber uint64
for _, trackEntry := range webmData.Segment.Tracks.TrackEntry {
if trackEntry.CodecID == "A_OPUS" {
opusTrackNumber = trackEntry.TrackNumber
}
}

if opusTrackNumber == 0 {
panic("Missing opus track")
}

buffer := make([]byte, 1920)
outputFile, err := os.Create(os.Args[2]) // #nosec G703
if err != nil {
panic(err)
}

decoder := opus.NewDecoder()
for _, cluster := range webmData.Segment.Cluster {
for _, simpleBlock := range cluster.SimpleBlock {
if simpleBlock.TrackNumber != opusTrackNumber {
continue
}

for _, data := range simpleBlock.Data {
_, _, err = decoder.Decode(data, buffer)
if err != nil {
panic(err)
}

_, err := outputFile.Write(buffer)
if err != nil {
panic(err)
}
}
}
}
}
Loading