-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathElmish.Audio.fs
102 lines (84 loc) · 3.39 KB
/
Elmish.Audio.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
module Elmish.Audio
open FSharp.Control.Tasks.ContextInsensitive
open Elmish
open System.Threading.Tasks
open System.Diagnostics
open System.IO
type Audio = {
Url : string option
Volume : float
}
let getMusikPlayerProcesses() = Process.GetProcessesByName("omxplayer.bin")
let setVolumeScript volume =
let volumeScript = "./volume.sh"
let txt = sprintf """export DBUS_SESSION_BUS_ADDRESS=$(cat /tmp/omxplayerdbus.root)
dbus-send --print-reply --session --reply-timeout=500 \
--dest=org.mpris.MediaPlayer2.omxplayer \
/org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Set \
string:"org.mpris.MediaPlayer2.Player" \
string:"Volume" double:%.2f""" volume
if File.Exists volumeScript then
File.Delete(volumeScript)
File.WriteAllText(volumeScript,txt.Replace("\r\n","\n").Replace("\r","\n"))
let p = new Process()
let startInfo = ProcessStartInfo()
startInfo.WorkingDirectory <- "./"
startInfo.FileName <- "sudo"
startInfo.Arguments <- "sh volume.sh"
startInfo.RedirectStandardOutput <- true
startInfo.UseShellExecute <- false
startInfo.CreateNoWindow <- true
p.StartInfo <- startInfo
p.Start() |> ignore
[<RequireQualifiedAccess>]
module Program =
let withAudio stoppedMsg (program:Elmish.Program<_,_,_,_>) =
let mutable lastView = None
let sendMsg file dispatch _args =
dispatch (stoppedMsg file)
let play dispatch file volume =
let p = new Process()
p.EnableRaisingEvents <- true
p.Exited.Add (sendMsg file dispatch)
let startInfo = ProcessStartInfo()
startInfo.FileName <- "omxplayer"
let volume = int (System.Math.Round(2000. * System.Math.Log10 volume))
startInfo.Arguments <- sprintf "--vol %d " volume + file
p.StartInfo <- startInfo
p.Start() |> ignore
let killMusikPlayer() = task {
for p in getMusikPlayerProcesses() do
if not p.HasExited then
try
let killP = new Process()
let startInfo = ProcessStartInfo()
startInfo.FileName <- "sudo"
startInfo.Arguments <- "kill -9 " + p.Id.ToString()
killP.StartInfo <- startInfo
killP.Start() |> ignore
while not p.HasExited do
do! Task.Delay 10
with _ -> ()
}
let mapSetState setState model dispatch =
let (v:Audio) = Program.view program model dispatch
match lastView with
| Some r when r = v -> ()
| Some r ->
if r.Url <> v.Url then
killMusikPlayer () |> Async.AwaitTask |> Async.RunSynchronously
if r.Url = v.Url && v.Url <> None && r.Volume <> v.Volume then
setVolumeScript v.Volume
match v.Url with
| Some url when v.Url <> r.Url ->
play dispatch url v.Volume
| _ -> ()
| _ ->
match v.Url with
| Some url ->
play dispatch url v.Volume
| _ -> ()
lastView <- Some v
setState model dispatch
program
|> Program.map id id id mapSetState id