Skip to content

Commit dc996be

Browse files
committed
UNTESTED store video clip properly
1 parent d1d51d3 commit dc996be

4 files changed

Lines changed: 55 additions & 21 deletions

File tree

cmd/trainbot/main.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ func detectTrainsForever(c config, trainsOut chan<- *stitch.Train) {
158158
MaxSpeedKPH: c.MaxSpeedKPH,
159159
MinLengthM: c.MinLengthM,
160160
MaxFrameCountPerSeq: c.MaxFrameCountPerSeq,
161+
TempDestDir: c.DataDir,
161162
})
162163
defer func() {
163164
train := stitcher.TryStitchAndReset()
@@ -251,12 +252,25 @@ func processTrains(store upload.DataStore, dbx *sqlx.DB, trainsIn <-chan *stitch
251252
}
252253

253254
// Dump GIF.
254-
err = imutil.DumpGIF(store.GetBlobPath(dbTrain.GIFFileName()), train.GIF)
255-
if err != nil {
256-
log.Err(err).Send()
257-
continue
255+
if train.GIF != nil {
256+
err = imutil.DumpGIF(store.GetBlobPath(dbTrain.GIFFileName()), train.GIF)
257+
if err != nil {
258+
log.Err(err).Send()
259+
continue
260+
}
261+
log.Debug().Str("gifFileName", dbTrain.GIFFileName()).Msg("wrote GIF")
262+
}
263+
264+
// Move Train Clip
265+
if train.TrainClip != nil {
266+
filename := dbTrain.FileNameWithExt(filepath.Ext(train.TrainClip.Path))
267+
err = os.Rename(train.TrainClip.Path, store.GetBlobPath(filename))
268+
if err != nil {
269+
log.Err(err).Send()
270+
continue
271+
}
272+
log.Debug().Str("trainClipFileName", filename).Msg("moved train clip")
258273
}
259-
log.Debug().Str("gifFileName", dbTrain.GIFFileName()).Msg("wrote GIF")
260274

261275
id, err := db.InsertTrain(dbx, *train)
262276
if err != nil {

internal/pkg/db/queries.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ func (t *Train) GIFFileName() string {
5353
return fmt.Sprintf("train_%s.gif", tsString)
5454
}
5555

56+
// FileNameWithExt returns a file name for this train with the given file extension, derived from timestamp.
57+
func (t Train) FileNameWithExt(extension string) string {
58+
tsString := t.StartTS.Format(fileTSFormat)
59+
return fmt.Sprintf("train_%s.%s", tsString, extension)
60+
}
61+
5662
// ImgFileName returns the image file name for this train (derived from timestamp).
5763
func (t *Train) ImgFileName() string {
5864
tsString := t.StartTS.Format(fileTSFormat)

internal/pkg/stitch/auto.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type Config struct {
2929
MaxSpeedKPH float64
3030
MinLengthM float64
3131
MaxFrameCountPerSeq int
32+
TempDestDir string
3233
}
3334

3435
func (c *Config) minPxPerFrame(framePeriodS float64) int {

internal/pkg/stitch/stitch.go

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"image/draw"
99
"image/gif"
1010
"math"
11+
"os"
1112
"time"
1213

1314
"github.com/go-gst/go-glib/glib"
@@ -119,8 +120,9 @@ type Train struct {
119120

120121
Conf Config
121122

122-
Image *image.RGBA `json:"-"`
123-
GIF *gif.GIF `json:"-"`
123+
Image *image.RGBA `json:"-"`
124+
GIF *gif.GIF `json:"-"`
125+
TrainClip *TrainClip `json:"-"`
124126
}
125127

126128
// LengthM returns the absolute length in m.
@@ -189,23 +191,28 @@ func createGIF(seq sequence, stitched image.Image) (*gif.GIF, error) {
189191
return &g, nil
190192
}
191193

192-
func createH264(seq sequence, stitched image.Image) (*gif.GIF, error) {
194+
func createH264(seq sequence, dest_dir string) (*TrainClip, error) {
193195
// https://github.com/go-gst/go-gst/blob/v1.4.0/examples/appsrc/main.go
194196

195-
// SW: x264enc
196-
// HW on RPi: v4l2h264enc
197-
// HW on PC AMD: va264enc
198-
199-
// appsrc ! x264enc ! mp4mux ! filesync location=/tmp/test.mp4
200-
201197
gst.Init(nil)
202198

199+
dest_file, err := os.CreateTemp(dest_dir, ".temp-createH264.mp4.*")
200+
if err != nil {
201+
return nil, err
202+
}
203+
dest_file.Close()
204+
dest_path := dest_file.Name()
205+
203206
pipeline, err := gst.NewPipeline("")
204207
if err != nil {
205208
return nil, err
206209
}
207210

211+
// SW: x264enc
212+
// HW on RPi: v4l2h264enc
213+
// HW on PC AMD: va264enc
208214
encoder := "x264enc"
215+
209216
elems, err := gst.NewElementMany("appsrc", "videoconvert", encoder, "h264parse", "mp4mux", "filesink")
210217
if err != nil {
211218
return nil, err
@@ -215,7 +222,7 @@ func createH264(seq sequence, stitched image.Image) (*gif.GIF, error) {
215222
gst.ElementLinkMany(elems...)
216223

217224
src := app.SrcFromElement(elems[0])
218-
elems[5].SetArg("location", "/tmp/test.mp4")
225+
elems[5].SetArg("location", dest_path)
219226

220227
// Specify the format we want to provide as application into the pipeline
221228
// by creating a video info with the given format and creating caps from it for the appsrc element.
@@ -241,11 +248,12 @@ func createH264(seq sequence, stitched image.Image) (*gif.GIF, error) {
241248

242249
// If we've reached the end of the palette, end the stream.
243250
if i == len(seq.frames) {
251+
log.Debug().Msg("all frames pushed to gstreamer appsrc")
244252
src.EndStream()
245253
return
246254
}
247255

248-
log.Debug().Int("frame", i).Msg("Producing frame")
256+
log.Trace().Int("frame", i).Msg("Producing frame")
249257

250258
// Create a buffer that can hold exactly one video RGBA frame.
251259
buffer := gst.NewBufferWithSize(videoInfo.Size())
@@ -273,7 +281,7 @@ func createH264(seq sequence, stitched image.Image) (*gif.GIF, error) {
273281
// Push the buffer onto the pipeline.
274282
self.PushBuffer(buffer)
275283

276-
log.Debug().Msg("buffer pushed")
284+
log.Trace().Msg("buffer pushed")
277285

278286
i++
279287
},
@@ -288,7 +296,7 @@ func createH264(seq sequence, stitched image.Image) (*gif.GIF, error) {
288296

289297
// Retrieve the bus from the pipeline and add a watch function
290298
pipeline.GetPipelineBus().AddWatch(func(msg *gst.Message) bool {
291-
log.Warn().Str("msg", msg.String()).Msg("gstreamer message")
299+
log.Debug().Str("msg", msg.String()).Msg("gstreamer message")
292300
switch msg.Type() {
293301
case gst.MessageEOS:
294302
//time.Sleep(5 * time.Second)
@@ -309,7 +317,7 @@ func createH264(seq sequence, stitched image.Image) (*gif.GIF, error) {
309317
mainLoop.Run()
310318
//mainLoop.RunError()
311319

312-
return nil, errors.New("look at /tmp/test.mp4 :)")
320+
return &TrainClip{Path: dest_path}, nil
313321
}
314322
func produceImageFrame(c color.Color) []uint8 {
315323
width := 300
@@ -327,6 +335,10 @@ func produceImageFrame(c color.Color) []uint8 {
327335
return img.Pix
328336
}
329337

338+
type TrainClip struct {
339+
Path string
340+
}
341+
330342
// fitAndStitch tries to stitch an image from a sequence.
331343
// Will first try to fit a constant acceleration speed model for smoothing.
332344
// Might modify seq (drops leading frames with no movement).
@@ -385,7 +397,7 @@ func fitAndStitch(seq sequence, c Config) (*Train, error) {
385397
}
386398

387399
//gif, err := createGIF(seq, img)
388-
gif, err := createH264(seq, img)
400+
trainClip, err := createH264(seq, c.TempDestDir)
389401
if err != nil {
390402
panic(err)
391403
}
@@ -399,6 +411,7 @@ func fitAndStitch(seq sequence, c Config) (*Train, error) {
399411
-a,
400412
c,
401413
img,
402-
gif,
414+
nil,
415+
trainClip,
403416
}, nil
404417
}

0 commit comments

Comments
 (0)