-
Notifications
You must be signed in to change notification settings - Fork 433
/
player_parse.go
59 lines (49 loc) · 1.37 KB
/
player_parse.go
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
package youtube
import (
"context"
"errors"
"fmt"
"log"
"os"
"path/filepath"
"regexp"
"strings"
)
type playerConfig []byte
var basejsPattern = regexp.MustCompile(`(/s/player/\w+/player_ias.vflset/\w+/base.js)`)
func (c *Client) getPlayerConfig(ctx context.Context, videoID string) (playerConfig, error) {
embedURL := fmt.Sprintf("https://youtube.com/embed/%s?hl=en", videoID)
embedBody, err := c.httpGetBodyBytes(ctx, embedURL)
if err != nil {
return nil, err
}
// example: /s/player/f676c671/player_ias.vflset/en_US/base.js
playerPath := string(basejsPattern.Find(embedBody))
if playerPath == "" {
return nil, errors.New("unable to find basejs URL in playerConfig")
}
// for debugging
var artifactName string
if artifactsFolder != "" {
parts := strings.SplitN(playerPath, "/", 5)
artifactName = "player-" + parts[3] + ".js"
linkName := filepath.Join(artifactsFolder, "video-"+videoID+".js")
if err := os.Symlink(artifactName, linkName); err != nil {
log.Printf("unable to create symlink %s: %v", linkName, err)
}
}
config := c.playerCache.Get(playerPath)
if config != nil {
return config, nil
}
config, err = c.httpGetBodyBytes(ctx, "https://youtube.com"+playerPath)
if err != nil {
return nil, err
}
// for debugging
if artifactName != "" {
writeArtifact(artifactName, config)
}
c.playerCache.Set(playerPath, config)
return config, nil
}