Live video on the AT Protocol

parse whip/whep in the subcommand flags

+83 -44
+68 -3
pkg/cmd/streamplace.go
··· 498 498 499 499 if cli.WHIPTest != "" { 500 500 group.Go(func() error { 501 - err := WHIP(strings.Split(cli.WHIPTest, " ")) 501 + // Parse WHIPTest string using the whip command's flag parser 502 + whipCmd := makeWhipCommand(build) 503 + args := strings.Split(cli.WHIPTest, " ") 504 + err := whipCmd.Run(ctx, append([]string{"streamplace", "whip"}, args...)) 502 505 log.Warn(ctx, "WHIP test complete, sleeping for 3 seconds and shutting down gstreamer") 503 506 time.Sleep(time.Second * 3) 504 507 // gst.Deinit() ··· 595 598 return &urfavecli.Command{ 596 599 Name: "whep", 597 600 Usage: "WHEP client", 601 + Flags: []urfavecli.Flag{ 602 + &urfavecli.IntFlag{ 603 + Name: "count", 604 + Usage: "number of concurrent streams (for load testing)", 605 + Value: 1, 606 + }, 607 + &urfavecli.DurationFlag{ 608 + Name: "duration", 609 + Usage: "stop after this long", 610 + }, 611 + &urfavecli.StringFlag{ 612 + Name: "endpoint", 613 + Usage: "endpoint to send the WHEP request to", 614 + }, 615 + }, 598 616 Action: func(ctx context.Context, cmd *urfavecli.Command) error { 599 - return WHEP(cmd.Args().Slice()) 617 + return WHEP( 618 + ctx, 619 + cmd.Int("count"), 620 + cmd.Duration("duration"), 621 + cmd.String("endpoint"), 622 + ) 600 623 }, 601 624 } 602 625 } ··· 605 628 return &urfavecli.Command{ 606 629 Name: "whip", 607 630 Usage: "WHIP client", 631 + Flags: []urfavecli.Flag{ 632 + &urfavecli.StringFlag{ 633 + Name: "stream-key", 634 + Usage: "stream key", 635 + }, 636 + &urfavecli.IntFlag{ 637 + Name: "count", 638 + Usage: "number of concurrent streams (for load testing)", 639 + Value: 1, 640 + }, 641 + &urfavecli.IntFlag{ 642 + Name: "viewers", 643 + Usage: "number of viewers to simulate per stream", 644 + }, 645 + &urfavecli.DurationFlag{ 646 + Name: "duration", 647 + Usage: "duration of the stream", 648 + }, 649 + &urfavecli.StringFlag{ 650 + Name: "file", 651 + Usage: "file to stream (needs to be an MP4 containing H264 video and Opus audio)", 652 + Required: true, 653 + }, 654 + &urfavecli.StringFlag{ 655 + Name: "endpoint", 656 + Usage: "endpoint to send the WHIP request to", 657 + Value: "http://127.0.0.1:38080", 658 + }, 659 + &urfavecli.DurationFlag{ 660 + Name: "freeze-after", 661 + Usage: "freeze the stream after the given duration", 662 + }, 663 + }, 608 664 Action: func(ctx context.Context, cmd *urfavecli.Command) error { 609 - return WHIP(cmd.Args().Slice()) 665 + return WHIP( 666 + ctx, 667 + cmd.String("stream-key"), 668 + cmd.Int("count"), 669 + cmd.Int("viewers"), 670 + cmd.Duration("duration"), 671 + cmd.String("file"), 672 + cmd.String("endpoint"), 673 + cmd.Duration("freeze-after"), 674 + ) 610 675 }, 611 676 } 612 677 }
+5 -17
pkg/cmd/whep.go
··· 2 2 3 3 import ( 4 4 "context" 5 - "flag" 6 5 "fmt" 7 6 "io" 8 7 "net/http" ··· 15 14 "stream.place/streamplace/pkg/log" 16 15 ) 17 16 18 - func WHEP(args []string) error { 19 - fs := flag.NewFlagSet("whep", flag.ExitOnError) 20 - count := fs.Int("count", 1, "number of concurrent streams (for load testing)") 21 - duration := fs.Duration("duration", 0, "stop after this long") 22 - endpoint := fs.String("endpoint", "", "endpoint to send the WHEP request to") 23 - err := fs.Parse(args) 24 - 25 - if err != nil { 26 - return err 27 - } 28 - 29 - ctx := context.Background() 30 - if *duration > 0 { 17 + func WHEP(ctx context.Context, count int, duration time.Duration, endpoint string) error { 18 + if duration > 0 { 31 19 var cancel context.CancelFunc 32 - ctx, cancel = context.WithTimeout(ctx, *duration) 20 + ctx, cancel = context.WithTimeout(ctx, duration) 33 21 defer cancel() 34 22 } 35 23 36 24 w := &WHEPClient{ 37 - Endpoint: *endpoint, 38 - Count: *count, 25 + Endpoint: endpoint, 26 + Count: count, 39 27 } 40 28 41 29 return w.WHEP(ctx)
+10 -24
pkg/cmd/whip.go
··· 2 2 3 3 import ( 4 4 "context" 5 - "flag" 6 5 "fmt" 7 6 "io" 8 7 "net/http" ··· 20 19 "stream.place/streamplace/pkg/media" 21 20 ) 22 21 23 - func WHIP(args []string) error { 24 - fs := flag.NewFlagSet("whip", flag.ExitOnError) 25 - streamKey := fs.String("stream-key", "", "stream key") 26 - count := fs.Int("count", 1, "number of concurrent streams (for load testing)") 27 - viewers := fs.Int("viewers", 0, "number of viewers to simulate per stream") 28 - duration := fs.Duration("duration", 0, "duration of the stream") 29 - file := fs.String("file", "", "file to stream (needs to be an MP4 containing H264 video and Opus audio)") 30 - endpoint := fs.String("endpoint", "http://127.0.0.1:38080", "endpoint to send the WHIP request to") 31 - freezeAfter := fs.Duration("freeze-after", 0, "freeze the stream after the given duration") 32 - err := fs.Parse(args) 33 - if *file == "" { 22 + func WHIP(ctx context.Context, streamKey string, count int, viewers int, duration time.Duration, file string, endpoint string, freezeAfter time.Duration) error { 23 + if file == "" { 34 24 return fmt.Errorf("file is required") 35 - } 36 - if err != nil { 37 - return err 38 25 } 39 26 gstinit.InitGST() 40 27 41 - ctx := context.Background() 42 - if *duration > 0 { 28 + if duration > 0 { 43 29 var cancel context.CancelFunc 44 - ctx, cancel = context.WithTimeout(ctx, *duration) 30 + ctx, cancel = context.WithTimeout(ctx, duration) 45 31 defer cancel() 46 32 } 47 33 48 34 w := &WHIPClient{ 49 - StreamKey: *streamKey, 50 - File: *file, 51 - Endpoint: *endpoint, 52 - Count: *count, 53 - FreezeAfter: *freezeAfter, 54 - Viewers: *viewers, 35 + StreamKey: streamKey, 36 + File: file, 37 + Endpoint: endpoint, 38 + Count: count, 39 + FreezeAfter: freezeAfter, 40 + Viewers: viewers, 55 41 } 56 42 57 43 return w.WHIP(ctx)