From eda7831fe1f3581884833a2560d2dce7dcddedcb Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Wed, 3 Nov 2021 14:25:00 +0100 Subject: [PATCH] Initial commit --- mpv_syndicate.nimble | 13 ++++++ src/mpv_syndicate.nim | 98 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 mpv_syndicate.nimble create mode 100644 src/mpv_syndicate.nim diff --git a/mpv_syndicate.nimble b/mpv_syndicate.nimble new file mode 100644 index 0000000..e299970 --- /dev/null +++ b/mpv_syndicate.nimble @@ -0,0 +1,13 @@ +# Package + +version = "0" +author = "Emery Hemingway" +description = "Syndicate wrapper for interacting with mpv" +license = "Unlicense" +srcDir = "src" +bin = @["mpv_syndicate"] + + +# Dependencies + +requires "nim >= 1.6.0", "syndicate" diff --git a/src/mpv_syndicate.nim b/src/mpv_syndicate.nim new file mode 100644 index 0000000..2ff3511 --- /dev/null +++ b/src/mpv_syndicate.nim @@ -0,0 +1,98 @@ +# SPDX-FileCopyrightText: ☭ 2021 Emery Hemingway +# SPDX-License-Identifier: Unlicense + +import std/[asyncdispatch, json, osproc, strutils] +import preserves, preserves/parse +import syndicate, syndicate/[actors, capabilities, dataspaces, patterns, relay], syndicate/protocols/service + +from std/os import getCurrentProcessId, commandLineParams, extractFilename, paramStr, sleep + +proc mint(): SturdyRef = + var key: array[16, byte] + mint(key, "syndicate") + +type + VideoEnqueue* {.preservesRecord: "playvideo".} = object + uri*: string + + VideoEnqueued* {.preservesRecord: "video-enqueued".} = object + uri*: string + pos*: int + +const videoPlayback = "video-playback" + +import std/net +from std/nativesockets import AF_UNIX, SOCK_DGRAM, Protocol + +type MpvProcess = ref object + process: Process + socket: Socket + +proc newMpvProcess(): MpvProcess = + let socketPath = "/tmp/mpvsocket-" & $getCurrentProcessId() + result = MpvProcess(process: startProcess("mpv", + args = ["--idle", "--input-ipc-server=" & socketPath], + options = {poUsePath, poParentStreams})) + sleep 500 + result.socket = newSocket( + domain = AF_UNIX, + sockType = SOCK_STREAM, + protocol = cast[Protocol](0), + buffered = false) + connectUnix(result.socket, socketPath) + +proc send(mpv: MpvProcess; command: varargs[string]) = + let js = %* {"command": command} + mpv.socket.send($js & "\n") + +proc recv(mpv: MpvProcess): JsonNode = + mpv.socket.recvLine.parseJson + +proc enqueue(mpv: MpvProcess; uri: string): int = + mpv.send "loadfile", uri, "append-play" + let js = mpv.recv() + +proc frontend() = + proc getUriParam(): string = + var params = commandLineParams() + case params.len + of 0: result = execProcess"wl-paste" + # take the clipboard if nothing on the command line + of 1: result = params[0] + else: + quit "too many parameters" + + waitFor runActor("chat") do (turn: var Turn): + + let cap = mint() + let uri = getUriParam() + + connectUnix(turn, "/run/syndicate/ds", cap) do (turn: var Turn; a: Assertion) -> TurnAction: + let ds = unembed a + + discard publish(turn, ds, RequireService[Ref](serviceName: toPreserve(videoPlayback, Ref))) + + onPublish(turn, ds, VideoEnqueued ? { 0: ?uri, 1: `?*`() }) do (pos: int): + # querying when a video is enqueued impiles that it should be enqueued? + echo uri, " enqueued at position ", pos + stopActor(turn) + + discard publish(turn, ds, VideoEnqueue(uri: uri)) + +proc backend() = + waitFor runActor("chat") do (turn: var Turn): + + let cap = mint() + + connectUnix(turn, "/run/syndicate/ds", cap) do (turn: var Turn; a: Assertion) -> TurnAction: + let + ds = unembed a + mpv = newMpvProcess() + + onPublish(turn, ds, VideoEnqueue ? { 0: `?*`() }) do (uri: string): + let pos = mpv.enqueue(uri) + discard publish(turn, ds, VideoEnqueued(uri: uri, pos: pos)) + +case extractFilename(paramStr 0) +of "mpv_syndicate": backend() +else: frontend()