Skip to content

Instantly share code, notes, and snippets.

@onionhammer
Created April 14, 2016 01:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save onionhammer/bcdfd7b56fbce73ad4a438925b033a75 to your computer and use it in GitHub Desktop.
Save onionhammer/bcdfd7b56fbce73ad4a438925b033a75 to your computer and use it in GitHub Desktop.
#load "load-project-debug.fsx"
// REF: https://github.com/MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL-/blob/master/docs/PlaybackAPI_WebSocket.md
open System
open System.Net.WebSockets
open System.Threading
open System.Threading.Tasks
open System.Text
open System.Text.RegularExpressions
open Newtonsoft.Json
let ws = new ClientWebSocket()
printf "Connecting..."
async { return! ws.ConnectAsync(new Uri("ws://localhost:5672"), CancellationToken.None) |> Async.AwaitTask }
|> Async.RunSynchronously
printfn "Done: %A" ws.State
// Receive information
let buffer = Array.zeroCreate 1024
let rec listen (ws: ClientWebSocket) =
let keepGoing =
async {
let seg = ArraySegment buffer
let! msg = ws.ReceiveAsync(seg, CancellationToken.None) |> Async.AwaitTask
return
match msg.MessageType with
| WebSocketMessageType.Close ->
printfn "> closed"
false
| WebSocketMessageType.Text ->
let str = Encoding.UTF8.GetString(buffer, 0, msg.Count)
printfn "%s" str
true
| _ ->
printfn "binary %A bytes" msg.Count
true
} |> Async.RunSynchronously
if keepGoing then listen ws
// listen ws
// Send Commands
let send (ws: ClientWebSocket) (value: string) =
let buffer = Encoding.UTF8.GetBytes(value)
let seg = ArraySegment buffer
async { return! ws.SendAsync(seg, WebSocketMessageType.Text, true, CancellationToken.None) |> Async.AwaitTask }
|> Async.RunSynchronously
type CommandArg =
// Volume =
| Volume_SetVolume of int
| Volume_IncreaseVolume of int
| Volume_DecreaseVolume of int
// Playback =
| Playback_SetPlayback of int
| Playback_PlayPause
| Playback_Forward
| Playback_Rewind
| Playback_ToggleShuffle
| Playback_ToggleRepeat
| Playback_ToggleVisualization
// Rating =
| Rating_ToggleThumbsUp
| Rating_ToggleThumbDown
| Rating_SetRating of int
| Rating_ResetRating
let command (x: CommandArg) =
let command channel command arg =
sprintf """{
"namespace": "%s",
"method": "%s",
"arguments": [%s]
}
""" channel command arg
let lowerFirst (s: string) =
string (Char.ToLower(s.[0])) + s.Substring(1)
match x with
| _ ->
printfn "%A" x
let reg = Regex @"^(?<namespace>\w+?)_(?<method>\w+?)( (?<arg>.+))?$"
let m = reg.Match( sprintf "%A" x )
match m.Success with
| true ->
let ns = lowerFirst (m.Groups.["namespace"].Value)
let cmd = lowerFirst (m.Groups.["method"].Value)
let arg = m.Groups.["arg"].Value
command ns cmd arg |> send ws
| false ->
failwith <| sprintf "Not Handled: %A" x
command Playback_PlayPause
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment