aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2021-11-18 17:59:09 +0000
committerdakkar <dakkar@thenautilus.net>2021-11-18 18:00:11 +0000
commit1b78ff16638f6f1089488f67afa4c55af62349fd (patch)
tree58cb8c60799df3da8e4ffd2d41fe06641ca2e37a
downloadmedia-control-1b78ff16638f6f1089488f67afa4c55af62349fd.tar.gz
media-control-1b78ff16638f6f1089488f67afa4c55af62349fd.tar.bz2
media-control-1b78ff16638f6f1089488f67afa4c55af62349fd.zip
very rought start
-rw-r--r--vlc.html58
-rw-r--r--vlc.raku102
2 files changed, 160 insertions, 0 deletions
diff --git a/vlc.html b/vlc.html
new file mode 100644
index 0000000..e33ac9a
--- /dev/null
+++ b/vlc.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>vlc</title>
+ <script>
+ "use strict"
+
+ function vlcCall(method,path,args) {
+ args ||= {};
+ let url=new URL(path,location.href);
+ for (let a in args) {
+ url.searchParams.set(a,args[a]);
+ }
+ return fetch(url, {
+ method: method,
+ mode: 'no-cors',
+ });
+ }
+
+ function vlcCommand(command,args) {
+ vlcCall('post',command,args);
+ }
+
+ async function updateView() {
+ const status = (await (await vlcCall('get','status')).json()).status;
+ const currentPos = document.querySelector('#current-pos');
+
+ if (status.state != 'playing') {
+ currentPos.disabled=true;
+ return;
+ }
+
+ currentPos.disabled=false;
+ const length = parseInt(status.length);
+
+ if (!length) { return }
+
+ const time = parseInt(status.time);
+ currentPos.max=length;
+ currentPos.value=time;
+ }
+
+ document.addEventListener('readystatechange', (event) => {
+ if (document.readyState == 'complete') {
+ setInterval(updateView, 1000);
+ }
+ })
+ </script>
+ </head>
+ <body>
+ <button onclick="vlcCommand('play')">play</button>
+ <button onclick="vlcCommand('pause')">pause</button>
+ <button onclick="vlcCommand('stop')">stop</button>
+ <button onclick="updateView()">update</button>
+ <input type="range" id="current-pos">
+ </body>
+</html>
diff --git a/vlc.raku b/vlc.raku
new file mode 100644
index 0000000..1e66776
--- /dev/null
+++ b/vlc.raku
@@ -0,0 +1,102 @@
+#!/usr/bin/env rakudo
+use v6.d;
+use Cro::HTTP::Server;
+use Cro::HTTP::Router;
+use Cro::HTTP::Client;
+use Cro::Uri::HTTP;
+use XML;
+use XML::XPath;
+use MIME::Base64;
+
+class VlcXMLParser does Cro::BodyParser {
+ method is-applicable(Cro::HTTP::Message $message --> Bool) {
+ with $message.content-type {
+ .type eq 'application'|'text' && .subtype eq 'xml' || .suffix eq 'json'
+ }
+ else {
+ False
+ }
+ }
+
+ method parse(Cro::HTTP::Message $message --> Promise) {
+ Promise(
+ supply {
+ my $payload = Blob.new;
+
+ whenever $message.body-byte-stream -> $blob {
+ $payload ~= $blob;
+ LAST emit from-xml($payload.decode('utf-8'));
+ }
+
+ # if we had LibXML
+
+ # my LibXML::PushParser $parser .= new();
+ #
+ # whenever $message.body-byte-stream -> $blob {
+ # $parser.push($blob);
+ # $payload ~= $blob;
+ # LAST emit $parser.finish-push;
+ # }
+ }
+ )
+ }
+}
+
+multi sub maybe-bool('true') { True }
+multi sub maybe-bool('false') { False }
+multi sub maybe-bool($x) { $x }
+
+sub xml-to-hash(XML::Element $elem) {
+ if $elem.elements() -> @children {
+ return %( @children.map: { .name => xml-to-hash($_) } )
+ }
+
+ return maybe-bool($elem.contents().join('').trim)
+}
+
+sub call-vlc(Str $path, *%args) {
+ my Cro::HTTP::Client $vlc .= new(
+ auth => { :username(), :password('ginopino') },
+ add-body-parsers => [ VlcXMLParser ],
+ );
+
+ state Cro::Uri::HTTP $base-uri .= parse('http://192.168.1.111:8080/requests/');
+
+ return $vlc.get(
+ $base-uri.add($path).add-query(|%args)
+ );
+}
+
+sub vlc-command(Str $command, *%args) {
+ return call-vlc('status.xml', :$command, |%args);
+}
+
+sub vlc-status() {
+ my $res = await call-vlc('status.xml');
+ my XML::Document $status = await $res.body;
+ return Promise.kept({:status(xml-to-hash($status.root))})
+}
+
+my $application = route {
+ get -> { static 'vlc.html' }
+
+ post -> 'play' { await vlc-command('pl_play') }
+ post -> 'pause' { await vlc-command('pl_pause') }
+ post -> 'stop' { await vlc-command('pl_stop') }
+
+ get -> 'status' {
+ my $status = await vlc-status();
+ content 'application/json', $status;
+ }
+};
+
+my Cro::Service $service = Cro::HTTP::Server.new(
+ :port(8080), :$application,
+);
+
+$service.start;
+
+react whenever signal(SIGINT) {
+ $service.stop;
+ exit;
+}