Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "bytes"
- "fmt"
- "io"
- "net/http"
- "strconv"
- "sync"
- "time"
- )
- func main() {
- var streams = [...]string{"https://c17.radioboss.fm:18509/stream"}
- var wg sync.WaitGroup
- for _, stream := range streams {
- time.Sleep(1 * time.Second)
- wg.Add(1)
- // Внимание, асинхронный вызов!
- go makePlaylist(stream, &wg)
- }
- // Ждём пока все асинхронные горутины завершатся
- wg.Wait()
- }
- func makePlaylist(streamAddress string, wg *sync.WaitGroup) {
- defer wg.Done()
- // Формируем HTTP-запрос
- client := &http.Client{}
- req, err := http.NewRequest("GET", streamAddress, nil)
- if err != nil {
- fmt.Println(fmt.Sprintf("%s error: %s", streamAddress, err))
- return
- }
- req.Header.Add("icy-metadata", "1")
- // Отправляем
- resp, err := client.Do(req)
- if err != nil {
- fmt.Println(fmt.Sprintf("%s error: %s", streamAddress, err))
- return
- }
- defer resp.Body.Close()
- // Получаем размер промежутка, через который сервер присылает информацию о текущем треке
- metaint, err := strconv.Atoi(resp.Header.Get("icy-metaint"))
- if err != nil {
- fmt.Println(fmt.Sprintf("%s error while getting icy-metaint: %s", streamAddress, err))
- return
- }
- if metaint < 1 {
- fmt.Println(fmt.Sprintf("%s sent incorrect icy-metaint value", streamAddress))
- return
- }
- // И читаем всё вот в этот буфер в бесконечном цикле
- buf := make([]byte, 65536)
- remaining := metaint
- for {
- // Читаем кусок потока (и никак не используем)
- l, err := resp.Body.Read(buf[:remaining])
- if err == io.EOF {
- break
- }
- if err != nil {
- fmt.Println(fmt.Sprintf("%s error: %s", streamAddress, err))
- break
- }
- remaining -= l
- if remaining > 0 {
- // Ещё не дочитали до информации о текущем треке
- continue
- }
- // Дочитали до информации о текущем треке — считываем её длину
- _, err = io.ReadAtLeast(resp.Body, buf[:1], 1)
- if err != nil {
- fmt.Println(fmt.Sprintf("%s error: %s", streamAddress, err))
- break
- }
- metalen := int(buf[0]) * 16
- if metalen < 1 {
- remaining = metaint
- continue
- }
- // И считываем информацию с этой длиной
- _, err = io.ReadAtLeast(resp.Body, buf[:metalen], metalen)
- if err != nil {
- fmt.Println(fmt.Sprintf("%s error: %s", streamAddress, err))
- break
- }
- // Готово
- streamInfo := string(bytes.Trim(buf[:metalen], "\x00"))
- fmt.Println(fmt.Sprintf("%s - %s", streamAddress, streamInfo))
- // Повторяем всё то же самое в следующей итерации цикла
- remaining = metaint
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement