mirror of
https://github.com/xaionaro-go/streamctl.git
synced 2025-10-24 16:10:31 +08:00
feat(twitch): Add flag --oauth-listen-port-twitch
This commit is contained in:
@@ -42,6 +42,9 @@ type Flags struct {
|
||||
Subprocess string `yaml:"Subprocess,omitempty"`
|
||||
SplitProcess bool `yaml:"SplitProcess,omitempty"`
|
||||
LockTimeout time.Duration `yaml:"LockTimeout,omitempty"`
|
||||
|
||||
OAuthListenPortTwitch uint16 `yaml:"OAuthListenPortTwitch,omitempty"`
|
||||
OAuthListenPortYouTube uint16 `yaml:"OAuthListenPortYouTube,omitempty"`
|
||||
}
|
||||
|
||||
var platformGetFlagsFuncs []func(*Flags)
|
||||
@@ -75,6 +78,9 @@ func parseFlags() Flags {
|
||||
subprocess := pflag.String("subprocess", "", "[internal use flag] run a specific sub-process (format: processName:addressToConnect)")
|
||||
splitProcess := pflag.Bool("split-process", !isMobile(), "split the process into multiple processes for better stability")
|
||||
lockTimeout := pflag.Duration("lock-timeout", 2*time.Minute, "[debug option] change the timeout for locking, before reporting it as a deadlock")
|
||||
oauthListenPortTwitch := pflag.Uint16("oauth-listen-port-twitch", 8091, "the port that is used for OAuth callbacks while authenticating in Twitch")
|
||||
oauthListenPortYouTube := pflag.Uint16("oauth-listen-port-youtube", 8092, "the port that is used for OAuth callbacks while authenticating in YouTube")
|
||||
|
||||
pflag.Parse()
|
||||
|
||||
flags := Flags{
|
||||
@@ -94,6 +100,9 @@ func parseFlags() Flags {
|
||||
Subprocess: *subprocess,
|
||||
SplitProcess: *splitProcess,
|
||||
LockTimeout: *lockTimeout,
|
||||
|
||||
OAuthListenPortTwitch: *oauthListenPortTwitch,
|
||||
OAuthListenPortYouTube: *oauthListenPortYouTube,
|
||||
}
|
||||
|
||||
for _, platformGetFlagsFunc := range platformGetFlagsFuncs {
|
||||
|
||||
@@ -69,7 +69,10 @@ func runPanel(
|
||||
logger.Debugf(ctx, "runPanel: %#+v", flags)
|
||||
defer logger.Debugf(ctx, "/runPanel")
|
||||
|
||||
var opts []streampanel.Option
|
||||
opts := []streampanel.Option{
|
||||
streampanel.OptionOAuthListenPortTwitch(flags.OAuthListenPortTwitch),
|
||||
streampanel.OptionOAuthListenPortYouTube(flags.OAuthListenPortYouTube),
|
||||
}
|
||||
if flags.RemoteAddr != "" {
|
||||
opts = append(opts, streampanel.OptionRemoteStreamDAddr(flags.RemoteAddr))
|
||||
}
|
||||
|
||||
@@ -82,3 +82,17 @@ func (c *Client) RecodingEndedChan(
|
||||
) (<-chan struct{}, error) {
|
||||
return nil, fmt.Errorf("not compiled with libav support")
|
||||
}
|
||||
|
||||
func (c *Client) CloseInput(
|
||||
ctx context.Context,
|
||||
inputID InputID,
|
||||
) error {
|
||||
return fmt.Errorf("not compiled with libav support")
|
||||
}
|
||||
|
||||
func (c *Client) CloseOutput(
|
||||
ctx context.Context,
|
||||
outputID OutputID,
|
||||
) error {
|
||||
return fmt.Errorf("not compiled with libav support")
|
||||
}
|
||||
|
||||
@@ -44,15 +44,26 @@ func New(
|
||||
if cfg.Config.ClientID == "" || cfg.Config.ClientSecret == "" {
|
||||
return nil, fmt.Errorf("'clientid' or/and 'clientsecret' is/are not set; go to https://dev.twitch.tv/console/apps/create and create an app if it not created, yet")
|
||||
}
|
||||
client, err := getClient(ctx, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
getPortsFn := cfg.Config.GetOAuthListenPorts
|
||||
if getPortsFn == nil {
|
||||
// TODO: find a way to adjust the OAuth ports dynamically without re-creating the Twitch client.
|
||||
return nil, fmt.Errorf("the function GetOAuthListenPorts is not set")
|
||||
}
|
||||
oauthPorts := getPortsFn()
|
||||
if len(oauthPorts) == 0 {
|
||||
return nil, fmt.Errorf("the function GetOAuthListenPorts returned zero ports")
|
||||
}
|
||||
|
||||
t := &Twitch{
|
||||
client: client,
|
||||
config: cfg,
|
||||
saveCfgFn: saveCfgFn,
|
||||
}
|
||||
client, err := getClient(ctx, cfg, oauthPorts[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.client = client
|
||||
var prevTokenUpdate time.Time
|
||||
client.OnUserAccessTokenRefreshed(func(newAccessToken, newRefreshToken string) {
|
||||
if twitchDebug == true {
|
||||
@@ -451,10 +462,6 @@ func (t *Twitch) getNewClientCode(
|
||||
) (_err error) {
|
||||
logger.Debugf(ctx, "getNewClientCode")
|
||||
defer func() { logger.Debugf(ctx, "/getNewClientCode: %v", _err) }()
|
||||
getPortsFn := t.config.Config.GetOAuthListenPorts
|
||||
if getPortsFn == nil {
|
||||
return fmt.Errorf("the function GetOAuthListenPorts is not set")
|
||||
}
|
||||
|
||||
oauthHandler := t.config.Config.CustomOAuthHandler
|
||||
if oauthHandler == nil {
|
||||
@@ -532,6 +539,13 @@ func (t *Twitch) getNewClientCode(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: either support only one port as in New, or support multiple
|
||||
// ports as we do below
|
||||
getPortsFn := t.config.Config.GetOAuthListenPorts
|
||||
if getPortsFn == nil {
|
||||
return fmt.Errorf("the function GetOAuthListenPorts is not set")
|
||||
}
|
||||
|
||||
for _, listenPort := range getPortsFn() {
|
||||
startHandlerForPort(listenPort)
|
||||
}
|
||||
@@ -628,14 +642,15 @@ func (t *Twitch) getNewTokenByApp(
|
||||
func getClient(
|
||||
ctx context.Context,
|
||||
cfg Config,
|
||||
oauthListenPort uint16,
|
||||
) (*helix.Client, error) {
|
||||
logger.Debugf(ctx, "getClient")
|
||||
logger.Debugf(ctx, "getClient(ctx, %#+v, %v)", cfg, oauthListenPort)
|
||||
defer logger.Debugf(ctx, "/getClient")
|
||||
|
||||
options := &helix.Options{
|
||||
ClientID: cfg.Config.ClientID,
|
||||
ClientSecret: cfg.Config.ClientSecret,
|
||||
RedirectURI: authRedirectURI(8091), // TODO: delete this hardcode
|
||||
RedirectURI: authRedirectURI(oauthListenPort), // TODO: delete this hardcode
|
||||
}
|
||||
client, err := helix.NewClient(options)
|
||||
if err != nil {
|
||||
|
||||
@@ -20,11 +20,19 @@ type BrowserConfig struct {
|
||||
Command string `yaml:"command"`
|
||||
}
|
||||
|
||||
type OAuthConfig struct {
|
||||
ListenPorts struct {
|
||||
Twitch uint16 `yaml:"twitch"`
|
||||
YouTube uint16 `yaml:"youtube"`
|
||||
} `yaml:"listen_ports"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
RemoteStreamDAddr string `yaml:"streamd_remote"`
|
||||
BuiltinStreamD streamd.Config `yaml:"streamd_builtin"`
|
||||
Screenshot ScreenshotConfig `yaml:"screenshot"`
|
||||
Browser BrowserConfig `yaml:"browser"`
|
||||
OAuth OAuthConfig `yaml:"oauth"`
|
||||
}
|
||||
|
||||
func DefaultConfig() Config {
|
||||
|
||||
@@ -18,3 +18,15 @@ type OptionRemoteStreamDAddr string
|
||||
func (o OptionRemoteStreamDAddr) Apply(cfg *Config) {
|
||||
cfg.RemoteStreamDAddr = string(o)
|
||||
}
|
||||
|
||||
type OptionOAuthListenPortTwitch uint16
|
||||
|
||||
func (o OptionOAuthListenPortTwitch) Apply(cfg *Config) {
|
||||
cfg.OAuth.ListenPorts.Twitch = uint16(o)
|
||||
}
|
||||
|
||||
type OptionOAuthListenPortYouTube uint16
|
||||
|
||||
func (o OptionOAuthListenPortYouTube) Apply(cfg *Config) {
|
||||
cfg.OAuth.ListenPorts.YouTube = uint16(o)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package streampanel
|
||||
|
||||
import "github.com/xaionaro-go/streamctl/pkg/streampanel/config"
|
||||
import (
|
||||
"github.com/xaionaro-go/streamctl/pkg/streampanel/config"
|
||||
)
|
||||
|
||||
type Config = config.Config
|
||||
type Option = config.Option
|
||||
type Options = config.Options
|
||||
type OptionRemoteStreamDAddr = config.OptionRemoteStreamDAddr
|
||||
|
||||
type OptionOAuthListenPortTwitch = config.OptionOAuthListenPortTwitch
|
||||
type OptionOAuthListenPortYouTube = config.OptionOAuthListenPortYouTube
|
||||
|
||||
@@ -322,10 +322,10 @@ func (p *Panel) Loop(ctx context.Context, opts ...LoopOption) error {
|
||||
// TODO: delete this hardcoding of the port
|
||||
defer closeLoadingWindow()
|
||||
streamD := p.StreamD.(*streamd.StreamD)
|
||||
streamD.AddOAuthListenPort(8091)
|
||||
streamD.AddOAuthListenPort(p.Config.OAuth.ListenPorts.Twitch)
|
||||
observability.Go(ctx, func() {
|
||||
<-ctx.Done()
|
||||
streamD.RemoveOAuthListenPort(8091)
|
||||
streamD.RemoveOAuthListenPort(p.Config.OAuth.ListenPorts.Twitch)
|
||||
})
|
||||
logger.Tracef(ctx, "started oauth listener for the local streamd")
|
||||
}
|
||||
@@ -367,7 +367,7 @@ func (p *Panel) startOAuthListenerForRemoteStreamD(
|
||||
streamD *client.Client,
|
||||
) error {
|
||||
ctx, cancelFn := context.WithCancel(ctx)
|
||||
receiver, listenPort, err := oauthhandler.NewCodeReceiver(ctx, 8091) // TODO: remove the hard-code of port 8091, currently it is needed because the port is hardcoded in Twitch
|
||||
receiver, listenPort, err := oauthhandler.NewCodeReceiver(ctx, p.Config.OAuth.ListenPorts.Twitch)
|
||||
if err != nil {
|
||||
cancelFn()
|
||||
return fmt.Errorf("unable to start listener for OAuth responses: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user