mirror of
https://github.com/onyx-and-iris/gobs-cli.git
synced 2026-04-18 15:13:39 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 82c0756dde | |||
| 4395c981c6 | |||
| dc043b5847 | |||
| c8a055fa28 | |||
| d9c0e40d8f | |||
| 42ab45b9fb | |||
| 27c3c5369b |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
# [0.11.0] - 2025-06-20
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- input list, scene list and sceneitem list now accept --uuid flag.
|
||||||
|
- Active column added to scene list table.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- scene list no longer prints the UUIDs by default, enable it with the --uuid flag.
|
||||||
|
|
||||||
|
# [0.10.3] - 2025-06-07
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- filter list:
|
||||||
|
- --ffmpeg, --vlc flags
|
||||||
|
- Muted column to list table
|
||||||
|
|
||||||
# [0.10.2] - 2025-06-04
|
# [0.10.2] - 2025-06-04
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -54,6 +54,10 @@ gobs-cli obs-version
|
|||||||
### SceneCmd
|
### SceneCmd
|
||||||
|
|
||||||
- list: List all scenes.
|
- list: List all scenes.
|
||||||
|
- flags:
|
||||||
|
|
||||||
|
*optional*
|
||||||
|
- --UUID: Display UUIDs of scenes.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
gobs-cli scene list
|
gobs-cli scene list
|
||||||
@@ -87,6 +91,10 @@ gobs-cli scene switch --preview LIVE
|
|||||||
### SceneItemCmd
|
### SceneItemCmd
|
||||||
|
|
||||||
- list: List all scene items.
|
- list: List all scene items.
|
||||||
|
- flags:
|
||||||
|
|
||||||
|
*optional*
|
||||||
|
- --UUID: Display UUIDs of scene items.
|
||||||
|
|
||||||
*optional*
|
*optional*
|
||||||
- args: SceneName
|
- args: SceneName
|
||||||
@@ -223,6 +231,9 @@ gobs-cli group status START "test_group"
|
|||||||
- --input: List all inputs.
|
- --input: List all inputs.
|
||||||
- --output: List all outputs.
|
- --output: List all outputs.
|
||||||
- --colour: List all colour sources.
|
- --colour: List all colour sources.
|
||||||
|
- --ffmpeg: List all ffmpeg sources.
|
||||||
|
- --vlc: List all VLC sources.
|
||||||
|
- --uuid: Display UUIDs of inputs.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
gobs-cli input list
|
gobs-cli input list
|
||||||
|
|||||||
70
input.go
70
input.go
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/andreykaipov/goobs/api/requests/inputs"
|
"github.com/andreykaipov/goobs/api/requests/inputs"
|
||||||
@@ -21,6 +22,9 @@ type InputListCmd struct {
|
|||||||
Input bool `flag:"" help:"List all inputs." aliases:"i"`
|
Input bool `flag:"" help:"List all inputs." aliases:"i"`
|
||||||
Output bool `flag:"" help:"List all outputs." aliases:"o"`
|
Output bool `flag:"" help:"List all outputs." aliases:"o"`
|
||||||
Colour bool `flag:"" help:"List all colour sources." aliases:"c"`
|
Colour bool `flag:"" help:"List all colour sources." aliases:"c"`
|
||||||
|
Ffmpeg bool `flag:"" help:"List all ffmpeg sources." aliases:"f"`
|
||||||
|
Vlc bool `flag:"" help:"List all VLC sources." aliases:"v"`
|
||||||
|
UUID bool `flag:"" help:"Display UUIDs of inputs." aliases:"u"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run executes the command to list all inputs.
|
// Run executes the command to list all inputs.
|
||||||
@@ -32,22 +36,64 @@ func (cmd *InputListCmd) Run(ctx *context) error {
|
|||||||
|
|
||||||
t := table.New(ctx.Out)
|
t := table.New(ctx.Out)
|
||||||
t.SetPadding(3)
|
t.SetPadding(3)
|
||||||
t.SetAlignment(table.AlignLeft, table.AlignLeft)
|
if cmd.UUID {
|
||||||
t.SetHeaders("Input Name", "Kind")
|
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignCenter, table.AlignLeft)
|
||||||
|
t.SetHeaders("Input Name", "Kind", "Muted", "UUID")
|
||||||
|
} else {
|
||||||
|
t.SetAlignment(table.AlignLeft, table.AlignLeft, table.AlignCenter)
|
||||||
|
t.SetHeaders("Input Name", "Kind", "Muted")
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(resp.Inputs, func(i, j int) bool {
|
||||||
|
return resp.Inputs[i].InputName < resp.Inputs[j].InputName
|
||||||
|
})
|
||||||
|
|
||||||
for _, input := range resp.Inputs {
|
for _, input := range resp.Inputs {
|
||||||
if cmd.Input && strings.Contains(input.InputKind, "input") {
|
var muteMark string
|
||||||
t.AddRow(input.InputName, input.InputKind)
|
resp, err := ctx.Client.Inputs.GetInputMute(
|
||||||
}
|
inputs.NewGetInputMuteParams().WithInputName(input.InputName),
|
||||||
if cmd.Output && strings.Contains(input.InputKind, "output") {
|
)
|
||||||
t.AddRow(input.InputName, input.InputKind)
|
if err != nil {
|
||||||
}
|
if err.Error() == "request GetInputMute: InvalidResourceState (604): The specified input does not support audio." {
|
||||||
if cmd.Colour && strings.Contains(input.InputKind, "color") { // nolint
|
muteMark = "N/A"
|
||||||
t.AddRow(input.InputName, input.InputKind)
|
} else {
|
||||||
|
return fmt.Errorf("failed to get input mute state: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
muteMark = getEnabledMark(resp.InputMuted)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cmd.Input && !cmd.Output && !cmd.Colour {
|
type filter struct {
|
||||||
t.AddRow(input.InputName, input.InputKind)
|
enabled bool
|
||||||
|
keyword string
|
||||||
|
}
|
||||||
|
filters := []filter{
|
||||||
|
{cmd.Input, "input"},
|
||||||
|
{cmd.Output, "output"},
|
||||||
|
{cmd.Colour, "color"}, // nolint: misspell
|
||||||
|
{cmd.Ffmpeg, "ffmpeg"},
|
||||||
|
{cmd.Vlc, "vlc"},
|
||||||
|
}
|
||||||
|
|
||||||
|
var added bool
|
||||||
|
for _, f := range filters {
|
||||||
|
if f.enabled && strings.Contains(input.InputKind, f.keyword) {
|
||||||
|
if cmd.UUID {
|
||||||
|
t.AddRow(input.InputName, input.InputKind, muteMark, input.InputUuid)
|
||||||
|
} else {
|
||||||
|
t.AddRow(input.InputName, input.InputKind, muteMark)
|
||||||
|
}
|
||||||
|
added = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !added && (!cmd.Input && !cmd.Output && !cmd.Colour && !cmd.Ffmpeg && !cmd.Vlc) {
|
||||||
|
if cmd.UUID {
|
||||||
|
t.AddRow(input.InputName, snakeCaseToTitleCase(input.InputKind), muteMark, input.InputUuid)
|
||||||
|
} else {
|
||||||
|
t.AddRow(input.InputName, snakeCaseToTitleCase(input.InputKind), muteMark)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Render()
|
t.Render()
|
||||||
|
|||||||
30
main.go
30
main.go
@@ -33,21 +33,21 @@ type CLI struct {
|
|||||||
Version VersionFlag `help:"Print gobs-cli version information and quit" name:"version" short:"v"`
|
Version VersionFlag `help:"Print gobs-cli version information and quit" name:"version" short:"v"`
|
||||||
|
|
||||||
ObsVersion ObsVersionCmd `help:"Print OBS client and websocket version." cmd:"" aliases:"v"`
|
ObsVersion ObsVersionCmd `help:"Print OBS client and websocket version." cmd:"" aliases:"v"`
|
||||||
Scene SceneCmd `help:"Manage scenes." cmd:"" aliases:"sc"`
|
Scene SceneCmd `help:"Manage scenes." cmd:"" aliases:"sc" group:"Scene"`
|
||||||
Sceneitem SceneItemCmd `help:"Manage scene items." cmd:"" aliases:"si"`
|
Sceneitem SceneItemCmd `help:"Manage scene items." cmd:"" aliases:"si" group:"Scene Item"`
|
||||||
Group GroupCmd `help:"Manage groups." cmd:"" aliases:"g"`
|
Group GroupCmd `help:"Manage groups." cmd:"" aliases:"g" group:"Group"`
|
||||||
Input InputCmd `help:"Manage inputs." cmd:"" aliases:"i"`
|
Input InputCmd `help:"Manage inputs." cmd:"" aliases:"i" group:"Input"`
|
||||||
Record RecordCmd `help:"Manage recording." cmd:"" aliases:"rec"`
|
Record RecordCmd `help:"Manage recording." cmd:"" aliases:"rec" group:"Recording"`
|
||||||
Stream StreamCmd `help:"Manage streaming." cmd:"" aliases:"st"`
|
Stream StreamCmd `help:"Manage streaming." cmd:"" aliases:"st" group:"Streaming"`
|
||||||
Scenecollection SceneCollectionCmd `help:"Manage scene collections." cmd:"" aliases:"scn"`
|
Scenecollection SceneCollectionCmd `help:"Manage scene collections." cmd:"" aliases:"scn" group:"Scene Collection"`
|
||||||
Profile ProfileCmd `help:"Manage profiles." cmd:"" aliases:"p"`
|
Profile ProfileCmd `help:"Manage profiles." cmd:"" aliases:"p" group:"Profile"`
|
||||||
Replaybuffer ReplayBufferCmd `help:"Manage replay buffer." cmd:"" aliases:"rb"`
|
Replaybuffer ReplayBufferCmd `help:"Manage replay buffer." cmd:"" aliases:"rb" group:"Replay Buffer"`
|
||||||
Studiomode StudioModeCmd `help:"Manage studio mode." cmd:"" aliases:"sm"`
|
Studiomode StudioModeCmd `help:"Manage studio mode." cmd:"" aliases:"sm" group:"Studio Mode"`
|
||||||
Virtualcam VirtualCamCmd `help:"Manage virtual camera." cmd:"" aliases:"vc"`
|
Virtualcam VirtualCamCmd `help:"Manage virtual camera." cmd:"" aliases:"vc" group:"Virtual Camera"`
|
||||||
Hotkey HotkeyCmd `help:"Manage hotkeys." cmd:"" aliases:"hk"`
|
Hotkey HotkeyCmd `help:"Manage hotkeys." cmd:"" aliases:"hk" group:"Hotkey"`
|
||||||
Filter FilterCmd `help:"Manage filters." cmd:"" aliases:"f"`
|
Filter FilterCmd `help:"Manage filters." cmd:"" aliases:"f" group:"Filter"`
|
||||||
Projector ProjectorCmd `help:"Manage projectors." cmd:"" aliases:"prj"`
|
Projector ProjectorCmd `help:"Manage projectors." cmd:"" aliases:"prj" group:"Projector"`
|
||||||
Screenshot ScreenshotCmd `help:"Take screenshots." cmd:"" aliases:"ss"`
|
Screenshot ScreenshotCmd `help:"Take screenshots." cmd:"" aliases:"ss" group:"Screenshot"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type context struct {
|
type context struct {
|
||||||
|
|||||||
28
scene.go
28
scene.go
@@ -16,7 +16,9 @@ type SceneCmd struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SceneListCmd provides a command to list all scenes.
|
// SceneListCmd provides a command to list all scenes.
|
||||||
type SceneListCmd struct{} // size = 0x0
|
type SceneListCmd struct {
|
||||||
|
UUID bool `flag:"" help:"Display UUIDs of scenes."`
|
||||||
|
}
|
||||||
|
|
||||||
// Run executes the command to list all scenes.
|
// Run executes the command to list all scenes.
|
||||||
func (cmd *SceneListCmd) Run(ctx *context) error {
|
func (cmd *SceneListCmd) Run(ctx *context) error {
|
||||||
@@ -25,14 +27,32 @@ func (cmd *SceneListCmd) Run(ctx *context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentScene, err := ctx.Client.Scenes.GetCurrentProgramScene()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
t := table.New(ctx.Out)
|
t := table.New(ctx.Out)
|
||||||
t.SetPadding(3)
|
t.SetPadding(3)
|
||||||
t.SetAlignment(table.AlignLeft, table.AlignLeft)
|
if cmd.UUID {
|
||||||
t.SetHeaders("Scene Name", "UUID")
|
t.SetAlignment(table.AlignLeft, table.AlignCenter, table.AlignLeft)
|
||||||
|
t.SetHeaders("Scene Name", "Active", "UUID")
|
||||||
|
} else {
|
||||||
|
t.SetAlignment(table.AlignLeft, table.AlignCenter)
|
||||||
|
t.SetHeaders("Scene Name", "Active")
|
||||||
|
}
|
||||||
|
|
||||||
slices.Reverse(scenes.Scenes)
|
slices.Reverse(scenes.Scenes)
|
||||||
for _, scene := range scenes.Scenes {
|
for _, scene := range scenes.Scenes {
|
||||||
t.AddRow(scene.SceneName, scene.SceneUuid)
|
var activeMark string
|
||||||
|
if scene.SceneName == currentScene.SceneName {
|
||||||
|
activeMark = getEnabledMark(true)
|
||||||
|
}
|
||||||
|
if cmd.UUID {
|
||||||
|
t.AddRow(scene.SceneName, activeMark, scene.SceneUuid)
|
||||||
|
} else {
|
||||||
|
t.AddRow(scene.SceneName, activeMark)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
t.Render()
|
t.Render()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
41
sceneitem.go
41
sceneitem.go
@@ -21,7 +21,8 @@ type SceneItemCmd struct {
|
|||||||
|
|
||||||
// SceneItemListCmd provides a command to list all scene items in a scene.
|
// SceneItemListCmd provides a command to list all scene items in a scene.
|
||||||
type SceneItemListCmd struct {
|
type SceneItemListCmd struct {
|
||||||
SceneName string `arg:"" help:"Name of the scene to list items from." default:""`
|
UUID bool `flag:"" help:"Display UUIDs of scene items."`
|
||||||
|
SceneName string ` help:"Name of the scene to list items from." arg:"" default:""`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run executes the command to list all scene items in a scene.
|
// Run executes the command to list all scene items in a scene.
|
||||||
@@ -47,8 +48,13 @@ func (cmd *SceneItemListCmd) Run(ctx *context) error {
|
|||||||
|
|
||||||
t := table.New(ctx.Out)
|
t := table.New(ctx.Out)
|
||||||
t.SetPadding(3)
|
t.SetPadding(3)
|
||||||
t.SetAlignment(table.AlignCenter, table.AlignLeft, table.AlignCenter, table.AlignCenter)
|
if cmd.UUID {
|
||||||
t.SetHeaders("Item ID", "Item Name", "In Group", "Enabled")
|
t.SetAlignment(table.AlignCenter, table.AlignLeft, table.AlignCenter, table.AlignCenter, table.AlignCenter)
|
||||||
|
t.SetHeaders("Item ID", "Item Name", "In Group", "Enabled", "UUID")
|
||||||
|
} else {
|
||||||
|
t.SetAlignment(table.AlignCenter, table.AlignLeft, table.AlignCenter, table.AlignCenter)
|
||||||
|
t.SetHeaders("Item ID", "Item Name", "In Group", "Enabled")
|
||||||
|
}
|
||||||
|
|
||||||
sort.Slice(resp.SceneItems, func(i, j int) bool {
|
sort.Slice(resp.SceneItems, func(i, j int) bool {
|
||||||
return resp.SceneItems[i].SceneItemID < resp.SceneItems[j].SceneItemID
|
return resp.SceneItems[i].SceneItemID < resp.SceneItems[j].SceneItemID
|
||||||
@@ -67,15 +73,30 @@ func (cmd *SceneItemListCmd) Run(ctx *context) error {
|
|||||||
})
|
})
|
||||||
|
|
||||||
for _, groupItem := range resp.SceneItems {
|
for _, groupItem := range resp.SceneItems {
|
||||||
t.AddRow(
|
if cmd.UUID {
|
||||||
fmt.Sprintf("%d", groupItem.SceneItemID),
|
t.AddRow(
|
||||||
groupItem.SourceName,
|
fmt.Sprintf("%d", groupItem.SceneItemID),
|
||||||
item.SourceName,
|
groupItem.SourceName,
|
||||||
getEnabledMark(item.SceneItemEnabled && groupItem.SceneItemEnabled),
|
item.SourceName,
|
||||||
)
|
getEnabledMark(item.SceneItemEnabled && groupItem.SceneItemEnabled),
|
||||||
|
groupItem.SourceUuid,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
t.AddRow(
|
||||||
|
fmt.Sprintf("%d", groupItem.SceneItemID),
|
||||||
|
groupItem.SourceName,
|
||||||
|
item.SourceName,
|
||||||
|
getEnabledMark(item.SceneItemEnabled && groupItem.SceneItemEnabled),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
t.AddRow(fmt.Sprintf("%d", item.SceneItemID), item.SourceName, "", getEnabledMark(item.SceneItemEnabled))
|
if cmd.UUID {
|
||||||
|
t.AddRow(fmt.Sprintf("%d", item.SceneItemID), item.SourceName, "",
|
||||||
|
getEnabledMark(item.SceneItemEnabled), item.SourceUuid)
|
||||||
|
} else {
|
||||||
|
t.AddRow(fmt.Sprintf("%d", item.SceneItemID), item.SourceName, "", getEnabledMark(item.SceneItemEnabled))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Render()
|
t.Render()
|
||||||
|
|||||||
4
util.go
4
util.go
@@ -16,9 +16,9 @@ func snakeCaseToTitleCase(snake string) string {
|
|||||||
|
|
||||||
func getEnabledMark(enabled bool) string {
|
func getEnabledMark(enabled bool) string {
|
||||||
if enabled {
|
if enabled {
|
||||||
return "\u2713" // green check mark
|
return "\u2713" // check mark
|
||||||
}
|
}
|
||||||
return "\u274c" // red cross mark
|
return "\u274c" // cross mark
|
||||||
}
|
}
|
||||||
|
|
||||||
func trimPrefix(s, prefix string) string {
|
func trimPrefix(s, prefix string) string {
|
||||||
|
|||||||
Reference in New Issue
Block a user