davo36
davo36

Reputation: 714

How to Use gobuffalo/packr with Golang

I'm trying to play a sound from Golang. It's a .wav file. And I want to package the .wav file into the executable using packr

I have created a very small project here: packr-test repository with the code.

When I run the executable (./packr-test) in it's default folder, the sound plays. But the problem I'm having is that when I move the executable to another directory, I get an error trying to play the sound file. Which I think probably means the sound file isn't being bundled up with the executable.

This is on Ubuntu. I'm using the 'play' command which is often installed by default, but if it's not there, can be done with:

sudo apt-get install sox
sudo apt-get install sox libsox-fmt-all

To use play command:

play file_name.extension

To save you looking it up, here is my Go code:

package main

import (
    "fmt"
    "os/exec"

    "github.com/gobuffalo/packr"
)

func main() {

    soundsBox := packr.NewBox("./sounds")
    if soundsBox.Has("IEEE_float_mono_32kHz.wav") {
        fmt.Println("It's there.")
    } else {
        fmt.Println("It's not there.")
    }

    args := []string{"-v20", "./sounds/IEEE_float_mono_32kHz.wav"}
    output, err := exec.Command("play", args...).Output()
    if err != nil {
        // Play command was not successful
        fmt.Println("Got an error.")
        fmt.Println(err.Error())
    } else {
        fmt.Println(string(output))
    }

}

Here is my output:

sudo ./packr-test 
It's there.
Got an error.
exit status 2

Upvotes: 4

Views: 2583

Answers (1)

Matt
Matt

Reputation: 3760

You're still referencing the file on the file system, even though you have it packed into the binary:

args := []string{"-v20", "./sounds/IEEE_float_mono_32kHz.wav"}
output, err := exec.Command("play", args...).Output()

You can grab the file data from your packr box like this:

bytes, err := soundsBox.FindBytes("IEEE_float_mono_32kHz.wav")

To execute the file with exec.Command() I think you'll have to write those bytes back to the file system:

err := ioutil.WriteFile("/tmp/IEEE_float_mono_32kHz.wav", bytes, 0755)
exec.Command("play", []string{"-v20", "/tmp/IEEE_float_mono_32kHz.wav"}

You might be able to pass your bytes to play via stdin, but that would depend on how the play binary works.

cmd.Stdin = bytes
cmd.Run()

Upvotes: 5

Related Questions