-
Notifications
You must be signed in to change notification settings - Fork 84
/
main.go
97 lines (79 loc) · 2.02 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package main
import (
"errors"
"flag"
"fmt"
"io"
"os"
"github.com/Eyevinn/mp4ff/mp4"
)
const (
appName = "resegmenter"
)
var usg = `%s is an example on how to resegment a fragmented file to a new target segment duration.
The duration is given in ticks (in the track timescale).
If no init segment in the input, the trex defaults will not be known which may cause an issue.
The input must be a fragmented file.
Usage of %s:
`
type options struct {
chunkDur uint64
verbose bool
}
func parseOptions(fs *flag.FlagSet, args []string) (*options, error) {
fs.Usage = func() {
fmt.Fprintf(os.Stderr, usg, appName, appName)
fmt.Fprintf(os.Stderr, "\n%s [options] infile outfile\n\noptions:\n", appName)
fs.PrintDefaults()
}
opts := options{}
fs.Uint64Var(&opts.chunkDur, "d", 0, "Required: chunk duration (ticks)")
fs.BoolVar(&opts.verbose, "v", false, "Verbose output")
err := fs.Parse(args[1:])
return &opts, err
}
func main() {
if err := run(os.Args, os.Stdout); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}
func run(args []string, w io.Writer) error {
fs := flag.NewFlagSet(appName, flag.ContinueOnError)
o, err := parseOptions(fs, args)
if err != nil {
if errors.Is(err, flag.ErrHelp) {
return nil
}
return err
}
if o.chunkDur == 0 {
fs.Usage()
return fmt.Errorf("chunk duration must be set (and positive)")
}
if len(fs.Args()) != 2 {
fs.Usage()
return fmt.Errorf("missing input or output file")
}
inFilePath := fs.Arg(0)
outFilePath := fs.Arg(1)
ifd, err := os.Open(inFilePath)
if err != nil {
return fmt.Errorf("error opening file: %w", err)
}
defer ifd.Close()
parsedMp4, err := mp4.DecodeFile(ifd)
if err != nil {
return fmt.Errorf("error decoding file: %w", err)
}
newMp4, err := Resegment(w, parsedMp4, o.chunkDur, o.verbose)
if err != nil {
return fmt.Errorf("error resegmenting: %w", err)
}
ofd, err := os.Create(outFilePath)
if err != nil {
return fmt.Errorf("error creating file: %w", err)
}
defer ofd.Close()
return newMp4.Encode(ofd)
}