discstation 0.1.20 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,94 @@
1
+ # Play a Red Book audio CD via Windows Media Player's COM control - mpv on
2
+ # Windows has no libcdio, so cdda:// is "disabled at compile-time" there.
3
+ # WMPlayer.OCX only actually plays when hosted in a real window with a
4
+ # message pump; a bare `New-Object -ComObject` never leaves playState
5
+ # "Ready". Runs as a tiny persistent process, polled by the caller:
6
+ #
7
+ # Commands: caller writes one command to $CmdFile (PAUSE | STOP | NEXT |
8
+ # PREV | VOL:<0-100>); this script deletes it once consumed. A file-based
9
+ # channel instead of stdin - a background thread reading Console stdin
10
+ # here crashed the whole process outright (a piped stdin under a
11
+ # powershell.exe launched via -File from a console-less pythonw.exe
12
+ # parent apparently isn't safe to read from a second thread).
13
+ # Status (stdout): TRACK:<0-based index> | DONE | ERROR:<message>
14
+ #
15
+ # Usage: play-audio-cd.ps1 <drive e.g. D:> <command file path>
16
+ param(
17
+ [Parameter(Mandatory = $true)] [string] $Drive,
18
+ [Parameter(Mandatory = $true)] [string] $CmdFile
19
+ )
20
+
21
+ $ErrorActionPreference = "Stop"
22
+ Add-Type -AssemblyName System.Windows.Forms
23
+
24
+ # Write-Output through a redirected/piped stdout (SSH, or Python's own
25
+ # subprocess.PIPE) buffers until the process exits instead of flushing
26
+ # per line - confirmed live (only the final "DONE" ever arrived; every
27
+ # "TRACK:" sent during actual playback was stuck in the buffer). Writing
28
+ # straight to the console stream and flushing after each line sidesteps
29
+ # PowerShell's own output-pipeline buffering.
30
+ function Send-Status([string]$msg) {
31
+ [Console]::Out.WriteLine($msg)
32
+ [Console]::Out.Flush()
33
+ }
34
+
35
+ try {
36
+ $form = New-Object System.Windows.Forms.Form
37
+ $form.Show()
38
+ [System.Windows.Forms.Application]::DoEvents()
39
+
40
+ $wmp = New-Object -ComObject WMPlayer.OCX.7
41
+ $drives = $wmp.cdromCollection
42
+ $target = $null
43
+ for ($i = 0; $i -lt $drives.count; $i++) {
44
+ if ($drives.Item($i).driveSpecifier.TrimEnd('\') -ieq $Drive.TrimEnd('\')) { $target = $drives.Item($i); break }
45
+ }
46
+ if (-not $target) { Send-Status "ERROR:No CD drive $Drive"; exit 2 }
47
+
48
+ $wmp.currentPlaylist = $target.playlist
49
+ $wmp.controls.play()
50
+ } catch {
51
+ Send-Status ("ERROR:" + $_.Exception.Message)
52
+ exit 1
53
+ }
54
+
55
+ $lastTrack = -1
56
+ while ($true) {
57
+ Start-Sleep -Milliseconds 200
58
+ [System.Windows.Forms.Application]::DoEvents()
59
+
60
+ if ($wmp.playState -eq 8) { Send-Status "DONE"; break } # wmppsMediaEnded
61
+
62
+ # currentItem.playlistIndex comes back empty on this drive/build -
63
+ # confirmed live - but .name reliably reads "Track N" for a CD
64
+ # playlist item, so parse the number out of that instead.
65
+ $track = -1
66
+ try {
67
+ $item = $wmp.controls.currentItem
68
+ if ($item -and $item.name -match 'Track\s+(\d+)') { $track = [int]$Matches[1] - 1 }
69
+ } catch {}
70
+ if ($track -ge 0 -and $track -ne $lastTrack) {
71
+ $lastTrack = $track
72
+ Send-Status "TRACK:$track"
73
+ }
74
+
75
+ if (Test-Path -LiteralPath $CmdFile) {
76
+ $line = (Get-Content -LiteralPath $CmdFile -Raw -ErrorAction SilentlyContinue)
77
+ Remove-Item -LiteralPath $CmdFile -ErrorAction SilentlyContinue
78
+ if ($line) {
79
+ $line = $line.Trim()
80
+ switch -Regex ($line) {
81
+ '^PAUSE$' {
82
+ if ($wmp.playState -eq 3) { $wmp.controls.pause() } else { $wmp.controls.play() }
83
+ }
84
+ '^STOP$' { $wmp.controls.stop(); Send-Status "DONE"; break }
85
+ '^NEXT$' { $wmp.controls.next() }
86
+ '^PREV$' { $wmp.controls.previous() }
87
+ '^VOL:(\d+)$' { $wmp.settings.volume = [Math]::Min(100, [Math]::Max(0, [int]$Matches[1])) }
88
+ }
89
+ }
90
+ }
91
+ }
92
+
93
+ try { $wmp.controls.stop(); $wmp.close() } catch {}
94
+ try { $form.Close() } catch {}