faiface/beep

youtube-dl URL to mp3 -> mp3: only layer3 (want 1; got 3) is supported

aaronleopold opened this issue · 5 comments

I am learning go and creating a small program to fetch audio urls (via youtube-dl) and feed them into beep to play. I'm currently alternating between two errors:

  1. mp3: mp3: only MPEG version 1 (want 3; got 0) is supported
  2. mp3: mp3: only layer3 (want 1; got 3) is supported

I get the former error from the resulting url of youtube-dl -i --get-url --extract-audio --audio-format mp3 'https://www.youtube.com/watch?v=fkM3nSz_qjc'
The URL returned will expire sometime soon I believe, but I will link it here

I get the latter error from the resulting url of youtube-dl -i --get-url --extract-audio -f 140 --audio-format mp3 'https://www.youtube.com/watch?v=fkM3nSz_qjc'
The URL returned will expire sometime soon I believe, but I will link it here

func getTestUrl() string {
	youtubeDl, err := exec.LookPath("youtube-dl")
	if err != nil {
		log.Fatalf("youtube-dl installation could not be found")
	}

	ydl := exec.Command(
		youtubeDl, 
		"--get-url", 
		"--extract-audio", 
		"--audio-format", 
		"mp3", 
		"https://www.youtube.com/watch?v=fkM3nSz_qjc",
	)

	link, err := ydl.Output()
	if err != nil {
		report(err)
	}

	return strings.TrimSpace(string(link))
}

func TestPlay() {
	resp, err := http.Get(getTestUrl())
	if err != nil {
		log.Fatalln(err)
	} else {
	        // looks something like --> &{0xc000224180 {0 0} false <nil> 0x427ada0 0x427ad20}
		fmt.Println(resp.Body)
	}

	streamer, format, err := mp3.Decode(resp.Body)
	if err != nil {
		report(err)
	}

	defer streamer.Close()

	speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
	speaker.Play(streamer)

	select {}
}

Additionally, I downloaded the second mp3 and attempted to load it locally with the same error:

func TestLocalPlay() {
	f,err := os.Open("test.mp3")

	fmt.Println(f) // &{0xc000068840}

	streamer, format, err := mp3.Decode(f)
	if err != nil {
		log.Fatal(err) // --> mp3: mp3: only layer3 (want 1; got 3) is supported
	}
	defer streamer.Close()

	speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
        speaker.Play(streamer)
}

Hey, I didn't download the files in time so I couldn't test. Could you try it with the master branch of beep?

go get -u github.com/faiface/beep@master

It uses some newer dependencies. It just doesn't have a tag yet so go get doesn't download it by default.

Hey Mark, thanks for replying! I just updated and got a different error:

&{0xc0001ac180 {0 0} false <nil> 0x427ae40 0x427adc0} # --> the resp.Body
mp3: mp3: MPEG version 2.5 is not supported # --> the different error
exit status 1

I also updated my original comment just to give a little more code context for how I'm obtaining the URL's

I think this is a bit difficult to fix on beep's end. The library that we use (github.com/hajimehoshi/go-mp3) doesn't support it. So either they need to implement this, which I think is not easy, or we need to use another library which does support it, which I'm not sure exists.

Beep supports some other formats besides mp3, and so does youtube-dl. I tried some other combinations but no luck. All formats gave me some kind of error. Although I didn't look far into why. I think your best bet is to convert the audio from youtube to a format that beep does support. youtube-dl may have some options using avconf or ffmpeg to do this for you. Or you could use avconf/ffmpeg yourself if that is not the case.

Okay, thanks for your help Mark! Since this is more of an issue with the go-mp3 dependency I can go ahead and just close this issue if that's your preference? I'll try and use some other formats as you suggested, but since I'm passing in the response body of the audio URL I'll have to do some digging. I'll spend time looking into some of the other post-processing options youtube-dl has (I know they use ffmpeg as the default).

Close it 👍 Feel free to reopen or create a new issue if you have more questions.