Skip to content

Commit

Permalink
test, generate pairing code
Browse files Browse the repository at this point in the history
  • Loading branch information
cbix committed Aug 31, 2016
1 parent f41d3a7 commit bcde5cf
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ _testmain.go
*.exe
*.test
*.prof
/gotubecast
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2016 Florian Hülsmann
Copyright (c) 2016 Florian Hülsmann <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
# gotubecast
DIY YouTube TV
gotubecast is a small Go program which you can use to make your own YouTube TV player.

It connects to the YouTube Leanback API and generates a text stream providing pairing codes, video IDs,
play/pause/seek/volume change commands etc. It doesn't have any dependencies and runs on any of the platforms supported by golang.
For example, use it on a Raspberry Pi in combination with youtube-dl and omxplayer for a DIY Chromecast clone or make a YouTube TV
extension for your favorite media center software.

Work in progress.
74 changes: 74 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package main

import (
"fmt"
"net/http"
"io/ioutil"
"net/url"
"encoding/json"
)

type LoungeTokenScreenList struct {
Screens []LoungeTokenScreenItem
}

type LoungeTokenScreenItem struct {
ScreenId string
LoungeToken string
Expiration uint64
}

func main() {
// screen id:
resp, err := http.Get("https://www.youtube.com/api/lounge/pairing/generate_screen_id")
if err != nil {
fmt.Println(err.Error())
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err.Error())
}
screenId := string(body)
fmt.Println("screen_id", screenId)

// lounge token:
resp, err = http.PostForm("https://www.youtube.com/api/lounge/pairing/get_lounge_token_batch", url.Values{"screen_ids": {screenId}})
if err != nil {
fmt.Println(err.Error())
return
}
defer resp.Body.Close()
body, err = ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err.Error())
}
tokenObj := new(LoungeTokenScreenList)
err = json.Unmarshal(body, &tokenObj)
if err != nil {
fmt.Println(err.Error())
return
}
tokenScreenItem := tokenObj.Screens[0]
fmt.Println("lounge_token", tokenScreenItem.LoungeToken, tokenScreenItem.Expiration / 1000)

// pairing code:
resp, err = http.PostForm("https://www.youtube.com/api/lounge/pairing/get_pairing_code?ctx=pair", url.Values{
"access_type": {"permanent"},
"app": {"golang-test-838"},
"lounge_token": {tokenScreenItem.LoungeToken},
"screen_id": {tokenScreenItem.ScreenId},
"screen_name": {"Golang Test TV"},
})
if err != nil {
fmt.Println(err.Error())
}
defer resp.Body.Close()
body, err = ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err.Error())
}
pairCode := string(body)
fmt.Printf("pairing_code %s-%s-%s-%s\n", pairCode[0:3], pairCode[3:6], pairCode[6:9], pairCode[9:12])
}

0 comments on commit bcde5cf

Please sign in to comment.