Live video on the AT Protocol
1package cmd
2
3import (
4 "bytes"
5 "context"
6 "crypto/ecdsa"
7 "flag"
8 "fmt"
9 "io"
10 "os"
11
12 "github.com/decred/dcrd/dcrec/secp256k1"
13 "github.com/mr-tron/base58"
14 "stream.place/streamplace/pkg/crypto/aqpub"
15 "stream.place/streamplace/pkg/media"
16)
17
18func Sign(ctx context.Context) error {
19 fs := flag.NewFlagSet("streamplace", flag.ExitOnError)
20 certPath := fs.String("cert", "", "path to the certificate file")
21 key := fs.String("key", "", "base58-encoded secp256k1 private key")
22 streamerName := fs.String("streamer", "", "streamer name")
23 taURL := fs.String("ta-url", "http://timestamp.digicert.com", "timestamp authority server for signing")
24 startTime := fs.Int64("start-time", 0, "start time of the stream")
25 fs.Parse(os.Args[2:])
26
27 keyBs, err := base58.Decode(*key)
28 if err != nil {
29 return err
30 }
31
32 if *streamerName == "" {
33 return fmt.Errorf("streamer name is required")
34 }
35
36 secpSigner, _ := secp256k1.PrivKeyFromBytes(keyBs)
37 if secpSigner == nil {
38 return fmt.Errorf("invalid key")
39 }
40 signer := secpSigner.ToECDSA()
41
42 certBs, err := os.ReadFile(*certPath)
43 if err != nil {
44 return err
45 }
46
47 pub, err := aqpub.FromPublicKey(signer.Public().(*ecdsa.PublicKey))
48
49 ms := &media.MediaSignerLocal{
50 Signer: signer,
51 Cert: certBs,
52 StreamerName: *streamerName,
53 TAURL: *taURL,
54 AQPub: pub,
55 }
56
57 inputBs, err := io.ReadAll(os.Stdin)
58 if err != nil {
59 return err
60 }
61
62 mp4, err := ms.SignMP4(ctx, bytes.NewReader(inputBs), *startTime)
63 io.Copy(os.Stdout, bytes.NewReader(mp4))
64
65 return nil
66}