-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathstream.go
More file actions
65 lines (55 loc) · 1.68 KB
/
stream.go
File metadata and controls
65 lines (55 loc) · 1.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package scdl
import (
"context"
"encoding/json"
"fmt"
"strings"
)
// GetStreamURL resolves the M3U8 playlist URL for a track.
func (c *Client) GetStreamURL(ctx context.Context, track *Track) (string, error) {
trackID, streamToken, err := parseHLSURL(track.HLSURL)
if err != nil {
return "", err
}
apiURL := fmt.Sprintf(
"https://api-v2.soundcloud.com/media/soundcloud:tracks:%s/%s/stream/hls?client_id=%s&track_authorization=%s",
trackID, streamToken, c.clientID, track.TrackAuthorization,
)
body, err := c.get(ctx, apiURL)
if err != nil {
return "", fmt.Errorf("fetch stream URL: %w", err)
}
var resp struct {
URL string `json:"url"`
}
if err := json.Unmarshal(body, &resp); err != nil {
return "", fmt.Errorf("parse stream response: %w", err)
}
if resp.URL == "" {
return "", fmt.Errorf("empty stream URL in API response")
}
return resp.URL, nil
}
// parseHLSURL extracts the track ID and stream token from an HLS URL like:
// https://api-v2.soundcloud.com/media/soundcloud:tracks:123456/ab-cd-ef/stream/hls
func parseHLSURL(hlsURL string) (trackID, streamToken string, err error) {
parts := strings.Split(hlsURL, "/")
if len(parts) < 6 {
return "", "", fmt.Errorf("invalid HLS URL format: %s", hlsURL)
}
// Find the part containing "soundcloud:tracks:"
for i, part := range parts {
if strings.HasPrefix(part, "soundcloud:tracks") {
idParts := strings.Split(part, ":")
if len(idParts) < 3 {
return "", "", fmt.Errorf("invalid track ID format in URL")
}
trackID = idParts[2]
if i+1 < len(parts) {
streamToken = parts[i+1]
}
return trackID, streamToken, nil
}
}
return "", "", fmt.Errorf("track ID not found in HLS URL: %s", hlsURL)
}