# 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()