Skip to content

Commit

Permalink
Get GPMF stream by id instead of hardcoding it (#82)
Browse files Browse the repository at this point in the history
* Get GPMF stream by id instead of hardcoding it

* Test max videos
  • Loading branch information
KonradIT authored Jan 7, 2023
1 parent 46d641f commit 851078f
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 3 deletions.
13 changes: 11 additions & 2 deletions pkg/gopro/location_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,29 @@ var videoTests = map[string]bool{
"hero6+ble.mp4": false,
"hero6.mp4": true,
"hero6a.mp4": true,

"hero7.mp4": false,
"hero8.mp4": false,
"max-360mode.mp4": true,
"max-heromode.mp4": true,
}

func TestParseGPMF(t *testing.T) {
ctx := context.Background()

fs, err := gitfs.New(ctx, "github.com/gopro/gpmf-parser/samples",
gitfs.OptGlob("hero[5..6]*.mp4"))
gitfs.OptGlob("*.mp4"))
require.NoError(t, err)

walk := fsutil.Walk(fs, "")
for walk.Step() {
if walk.Path() == "" {
walk.Step()
}
if _, found := videoTests[walk.Path()]; !found {
walk.Step()
}

fmt.Printf("\tTesting [%s]", walk.Path())

remoteFile, err := fs.Open(walk.Path())
Expand All @@ -43,7 +52,7 @@ func TestParseGPMF(t *testing.T) {
stat, err := remoteFile.Stat()
require.NoError(t, err)

buf := make([]byte, stat.Size()) // roughly 290 bytes per SRT entry
buf := make([]byte, stat.Size())

_, err = remoteFile.Read(buf)
require.NoError(t, err)
Expand Down
34 changes: 34 additions & 0 deletions pkg/utils/ffprobe.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ type GPSLocation struct {
} `json:"format"`
}

type StreamsResponse struct {
Streams []struct {
Index int `json:"index"`
CodecTagString string `json:"codec_tag_string"`
} `json:"streams"`
}

func NewFFprobe(path *string) FFprobe {
ff := FFprobe{}
if path == nil {
Expand Down Expand Up @@ -107,6 +114,33 @@ func (f *FFprobe) executeGetInfo(path string, entries ...string) ([]byte, error)
return out.Bytes(), nil
}

func (f *FFprobe) Streams(path string) (*StreamsResponse, error) {
result := StreamsResponse{}

args := []string{
"-show_streams",
"-of",
"json",
path,
}
_, err := os.Stat(path)
if err != nil {
return nil, err
}
cmd := exec.Command(f.ProgramPath, args...) // #nosec
var out bytes.Buffer
cmd.Stdout = &out
err = cmd.Run()
if err != nil {
return nil, err
}
err = json.Unmarshal(out.Bytes(), &result)
if err != nil {
return nil, err
}
return &result, nil
}

func (f *FFprobe) VideoSize(path string) (*VideoSizeResponse, error) {
result := VideoSizeResponse{}
out, err := f.executeGetInfo(path, "width", "height", "r_frame_rate")
Expand Down
14 changes: 13 additions & 1 deletion pkg/videomanipulation/ffmpeg.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"
"sync"

"github.com/konradit/mmt/pkg/utils"
"github.com/vbauerster/mpb/v8"
"github.com/xfrr/goffmpeg/ffmpeg"
"github.com/xfrr/goffmpeg/transcoder"
Expand Down Expand Up @@ -147,8 +148,19 @@ func (v *VMan) ExtractGPMF(input string) (*[]byte, error) {
if err != nil {
return nil, err
}
ffprobe := utils.NewFFprobe(nil)

v.trans.MediaFile().SetRawOutputArgs([]string{"-map", "0:3"})
streams, err := ffprobe.Streams(input)
if err != nil {
return nil, err
}
gpmfStream := 3
for _, stream := range streams.Streams {
if stream.CodecTagString == "gpmd" {
gpmfStream = stream.Index
}
}
v.trans.MediaFile().SetRawOutputArgs([]string{"-map", fmt.Sprintf("0:%d", gpmfStream)})
v.trans.MediaFile().SetOutputFormat("rawvideo")
v.trans.MediaFile().SetVideoCodec("copy")

Expand Down

0 comments on commit 851078f

Please sign in to comment.