mirror of
https://github.com/xaionaro-go/streamctl.git
synced 2025-10-06 16:07:11 +08:00
188 lines
3.8 KiB
Go
188 lines
3.8 KiB
Go
package obs
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/andreykaipov/goobs"
|
|
"github.com/facebookincubator/go-belt/tool/logger"
|
|
"github.com/hashicorp/go-multierror"
|
|
"github.com/xaionaro-go/streamctl/pkg/streamcontrol"
|
|
)
|
|
|
|
type OBS struct {
|
|
Config Config
|
|
CurrentStream struct {
|
|
EnableRecording bool
|
|
}
|
|
}
|
|
|
|
var _ streamcontrol.StreamController[StreamProfile] = (*OBS)(nil)
|
|
|
|
func New(
|
|
ctx context.Context,
|
|
cfg Config,
|
|
) (*OBS, error) {
|
|
if cfg.Config.Host == "" {
|
|
return nil, fmt.Errorf("'host' is not set")
|
|
}
|
|
if cfg.Config.Port == 0 {
|
|
return nil, fmt.Errorf("'port' is not set")
|
|
}
|
|
|
|
return &OBS{
|
|
Config: cfg,
|
|
}, nil
|
|
}
|
|
|
|
func (obs *OBS) getClient() (*goobs.Client, error) {
|
|
var opts []goobs.Option
|
|
if obs.Config.Config.Password != "" {
|
|
opts = append(opts, goobs.WithPassword(obs.Config.Config.Password))
|
|
}
|
|
return goobs.New(
|
|
fmt.Sprintf("%s:%d", obs.Config.Config.Host, obs.Config.Config.Port),
|
|
opts...,
|
|
)
|
|
}
|
|
|
|
func (obs *OBS) Close() error {
|
|
return nil
|
|
}
|
|
|
|
func (obs *OBS) ApplyProfile(
|
|
ctx context.Context,
|
|
profile StreamProfile,
|
|
customArgs ...any,
|
|
) error {
|
|
return fmt.Errorf("not supported")
|
|
}
|
|
|
|
func (obs *OBS) SetTitle(
|
|
ctx context.Context,
|
|
title string,
|
|
) error {
|
|
// So nothing to do here:
|
|
return nil
|
|
}
|
|
|
|
func (obs *OBS) SetDescription(
|
|
ctx context.Context,
|
|
description string,
|
|
) error {
|
|
// So nothing to do here:
|
|
return nil
|
|
}
|
|
|
|
func (obs *OBS) InsertAdsCuePoint(
|
|
ctx context.Context,
|
|
ts time.Time,
|
|
duration time.Duration,
|
|
) error {
|
|
// So nothing to do here:
|
|
return nil
|
|
}
|
|
|
|
func (obs *OBS) Flush(
|
|
ctx context.Context,
|
|
) error {
|
|
// So nothing to do here:
|
|
return nil
|
|
}
|
|
|
|
func (obs *OBS) StartStream(
|
|
ctx context.Context,
|
|
title string,
|
|
description string,
|
|
profile StreamProfile,
|
|
customArgs ...any,
|
|
) error {
|
|
client, err := obs.getClient()
|
|
if err != nil {
|
|
return fmt.Errorf("unable to initialize client to OBS: %w", err)
|
|
}
|
|
defer client.Disconnect()
|
|
|
|
streamStatus, err := client.Stream.GetStreamStatus()
|
|
if err != nil {
|
|
return fmt.Errorf("unable to get current stream status: %w", err)
|
|
}
|
|
|
|
recordingStarted := false
|
|
if profile.EnableRecording {
|
|
recordStatus, err := client.Record.GetRecordStatus()
|
|
if err != nil {
|
|
return fmt.Errorf("unable to get current recording status: %w", err)
|
|
}
|
|
|
|
if !recordStatus.OutputActive {
|
|
_, recordStartErr := client.Record.StartRecord()
|
|
if recordStartErr == nil {
|
|
recordingStarted = true
|
|
} else {
|
|
err = multierror.Append(err, recordStartErr)
|
|
}
|
|
}
|
|
}
|
|
|
|
if !streamStatus.OutputActive {
|
|
_, streamStartErr := client.Stream.StartStream()
|
|
if streamStartErr != nil {
|
|
err = multierror.Append(err, streamStartErr)
|
|
}
|
|
}
|
|
|
|
if err != nil {
|
|
if recordingStarted {
|
|
_, e0 := client.Record.StopRecord()
|
|
logger.Debugf(ctx, "StopRecord result: %v", e0)
|
|
}
|
|
_, e1 := client.Stream.StopStream()
|
|
logger.Debugf(ctx, "StopStream result: %v", e1)
|
|
|
|
return err
|
|
}
|
|
|
|
obs.CurrentStream.EnableRecording = profile.EnableRecording
|
|
return nil
|
|
}
|
|
|
|
func (obs *OBS) EndStream(
|
|
ctx context.Context,
|
|
) error {
|
|
client, err := obs.getClient()
|
|
if err != nil {
|
|
return fmt.Errorf("unable to initialize client to OBS: %w", err)
|
|
}
|
|
defer client.Disconnect()
|
|
|
|
streamStatus, err := client.Stream.GetStreamStatus()
|
|
if err != nil {
|
|
return fmt.Errorf("unable to get current stream status: %w", err)
|
|
}
|
|
|
|
if obs.CurrentStream.EnableRecording {
|
|
recordStatus, err := client.Record.GetRecordStatus()
|
|
if err != nil {
|
|
return fmt.Errorf("unable to get current recording status: %w", err)
|
|
}
|
|
|
|
if recordStatus.OutputActive {
|
|
_, recordStopErr := client.Record.StopRecord()
|
|
if recordStopErr != nil {
|
|
err = multierror.Append(err, recordStopErr)
|
|
}
|
|
}
|
|
}
|
|
|
|
if streamStatus.OutputActive {
|
|
_, streamStopErr := client.Stream.StopStream()
|
|
if streamStopErr != nil {
|
|
err = multierror.Append(err, streamStopErr)
|
|
}
|
|
}
|
|
|
|
return err
|
|
}
|