feat: enqueue streams in running player
This commit is contained in:
@@ -6,6 +6,7 @@ enum PlayerCommand {
|
||||
case launch(URL?, newInstance: Bool, noConfig: Bool, progressFile: URL?)
|
||||
case launchSource(sourceFile: URL, newInstance: Bool, noConfig: Bool, progressFile: URL?)
|
||||
case launchQueue(queueFile: URL, newInstance: Bool, noConfig: Bool)
|
||||
case enqueue(queueFile: URL, noConfig: Bool)
|
||||
|
||||
static let usage = """
|
||||
Usage: terebi [--new-instance] [--no-config] [FILE | STREAM_URL]
|
||||
@@ -13,6 +14,7 @@ enum PlayerCommand {
|
||||
terebi --new-instance --url STREAM_URL --progress-file PATH
|
||||
terebi --new-instance --source-file PATH [--progress-file PATH]
|
||||
terebi --new-instance [--no-config] --queue-file PATH
|
||||
terebi --enqueue [--no-config] --queue-file PATH
|
||||
terebi [--new-instance] [--no-config] -- FILE
|
||||
terebi --help
|
||||
terebi --default-config
|
||||
@@ -26,6 +28,8 @@ enum PlayerCommand {
|
||||
--url URL Open a YouTube video or Miruro episode URL.
|
||||
--source-file PATH Open a validated resolved HTTP(S) source in a new player.
|
||||
--queue-file PATH Open an ordered version-1 stream queue with per-item reports.
|
||||
--enqueue Append a queue to the running player without interrupting playback;
|
||||
launch and start its first item if no player is running.
|
||||
--progress-file PATH Write JSONL playback facts to a new private file; requires
|
||||
--new-instance. The GUI owns reporting after this CLI exits.
|
||||
-- Treat the following argument as a filename, even with a leading '-'.
|
||||
@@ -58,16 +62,23 @@ enum PlayerCommand {
|
||||
}
|
||||
var newInstance = false
|
||||
var noConfig = false
|
||||
while let option = inputs.first, option == "--new-instance" || option == "--no-config" {
|
||||
var enqueue = false
|
||||
while let option = inputs.first, ["--new-instance", "--no-config", "--enqueue"].contains(option) {
|
||||
if option == "--new-instance" {
|
||||
guard !newInstance else { throw ArgumentError("--new-instance may only be supplied once.") }
|
||||
newInstance = true
|
||||
} else if option == "--enqueue" {
|
||||
guard !enqueue else { throw ArgumentError("--enqueue may only be supplied once.") }
|
||||
enqueue = true
|
||||
} else {
|
||||
guard !noConfig else { throw ArgumentError("--no-config may only be supplied once.") }
|
||||
noConfig = true
|
||||
}
|
||||
inputs.removeFirst()
|
||||
}
|
||||
guard !enqueue || (!newInstance && progressFile == nil && inputs.first == "--queue-file") else {
|
||||
throw ArgumentError("--enqueue requires --queue-file and cannot combine with --new-instance, --progress-file or other media.")
|
||||
}
|
||||
func launch(_ url: URL?) throws -> PlayerCommand {
|
||||
guard progressFile == nil || newInstance else {
|
||||
throw ArgumentError("--progress-file requires --new-instance.")
|
||||
@@ -94,12 +105,13 @@ enum PlayerCommand {
|
||||
return .printDefaultConfig
|
||||
}
|
||||
if inputs.first == "--queue-file" {
|
||||
guard newInstance, progressFile == nil, inputs.count == 2,
|
||||
guard newInstance || enqueue, progressFile == nil, inputs.count == 2,
|
||||
inputs[1].hasPrefix("/"), !inputs[1].contains("\0") else {
|
||||
throw ArgumentError("--queue-file requires --new-instance and one absolute manifest path; it cannot be combined with --progress-file.")
|
||||
throw ArgumentError("--queue-file requires --new-instance or --enqueue and one absolute manifest path; it cannot be combined with --progress-file.")
|
||||
}
|
||||
let queueFile = URL(fileURLWithPath: inputs[1]).standardizedFileURL
|
||||
_ = try StreamQueue.load(from: queueFile)
|
||||
if enqueue { return .enqueue(queueFile: queueFile, noConfig: noConfig) }
|
||||
return .launchQueue(queueFile: queueFile, newInstance: newInstance, noConfig: noConfig)
|
||||
}
|
||||
if inputs.first == "--source-file" {
|
||||
|
||||
Reference in New Issue
Block a user