mirror of
https://github.com/fxkt-tech/liv
synced 2025-09-27 04:16:00 +08:00
feat: snapshot frame_type add 2
This commit is contained in:
41
examples/ffmpeg/amix/main.go
Normal file
41
examples/ffmpeg/amix/main.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/fxkt-tech/liv/ffmpeg"
|
||||||
|
"github.com/fxkt-tech/liv/ffmpeg/codec"
|
||||||
|
"github.com/fxkt-tech/liv/ffmpeg/filter"
|
||||||
|
"github.com/fxkt-tech/liv/ffmpeg/input"
|
||||||
|
"github.com/fxkt-tech/liv/ffmpeg/output"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var (
|
||||||
|
ctx = context.Background()
|
||||||
|
input1 = input.WithSimple("a1.aac")
|
||||||
|
input2 = input.WithSimple("a2.aac")
|
||||||
|
fAmix = filter.AMix(2)
|
||||||
|
)
|
||||||
|
|
||||||
|
err := ffmpeg.New(
|
||||||
|
ffmpeg.WithLogLevel(""),
|
||||||
|
ffmpeg.WithDebug(true),
|
||||||
|
ffmpeg.WithDry(true),
|
||||||
|
).AddInput(
|
||||||
|
input1, input2,
|
||||||
|
).AddFilter(
|
||||||
|
fAmix,
|
||||||
|
).
|
||||||
|
AddOutput(
|
||||||
|
output.New(
|
||||||
|
output.Map(fAmix),
|
||||||
|
output.AudioCodec(codec.AAC),
|
||||||
|
output.File("out.mp4"),
|
||||||
|
),
|
||||||
|
).Run(ctx)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
@@ -19,7 +19,7 @@ func main() {
|
|||||||
err := ffmpeg.New(
|
err := ffmpeg.New(
|
||||||
ffmpeg.WithLogLevel(""),
|
ffmpeg.WithLogLevel(""),
|
||||||
ffmpeg.WithDebug(true),
|
ffmpeg.WithDebug(true),
|
||||||
// ffmpeg.Dry(true),
|
ffmpeg.WithDry(true),
|
||||||
).AddInput(
|
).AddInput(
|
||||||
input1,
|
input1,
|
||||||
).AddOutput(
|
).AddOutput(
|
||||||
|
@@ -15,8 +15,9 @@ func main() {
|
|||||||
Infile: "../../testdata/in.mp4",
|
Infile: "../../testdata/in.mp4",
|
||||||
Outfile: "ss/simple-%05d.jpg",
|
Outfile: "ss/simple-%05d.jpg",
|
||||||
StartTime: 0,
|
StartTime: 0,
|
||||||
// FrameType: 1,
|
FrameType: 2,
|
||||||
Num: 4,
|
Frames: []int32{1, 10, 300, 301},
|
||||||
|
// Num: 4,
|
||||||
// Interval: 5,
|
// Interval: 5,
|
||||||
Width: 960,
|
Width: 960,
|
||||||
Height: 540,
|
Height: 540,
|
||||||
|
@@ -82,14 +82,13 @@ func (ff *FFmpeg) DryRun() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ff *FFmpeg) Run(ctx context.Context) (err error) {
|
func (ff *FFmpeg) Run(ctx context.Context) (err error) {
|
||||||
if ff.debug {
|
|
||||||
ff.DryRun()
|
|
||||||
} else {
|
|
||||||
if ff.dry {
|
if ff.dry {
|
||||||
ff.DryRun()
|
ff.DryRun()
|
||||||
return nil
|
return nil
|
||||||
|
} else if ff.debug {
|
||||||
|
ff.DryRun()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
cc := exec.CommandContext(ctx, ff.bin, ff.Params()...)
|
cc := exec.CommandContext(ctx, ff.bin, ff.Params()...)
|
||||||
retbytes, err := cc.CombinedOutput()
|
retbytes, err := cc.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
16
snapshot.go
16
snapshot.go
@@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/fxkt-tech/liv/ffmpeg/stream"
|
"github.com/fxkt-tech/liv/ffmpeg/stream"
|
||||||
"github.com/fxkt-tech/liv/ffprobe"
|
"github.com/fxkt-tech/liv/ffprobe"
|
||||||
"github.com/fxkt-tech/liv/pkg/math"
|
"github.com/fxkt-tech/liv/pkg/math"
|
||||||
|
"github.com/fxkt-tech/liv/pkg/sugar"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Snapshot struct {
|
type Snapshot struct {
|
||||||
@@ -54,12 +55,12 @@ func (ss *Snapshot) Simple(ctx context.Context, params *SnapshotParams) error {
|
|||||||
lastFilter := stream.V(0)
|
lastFilter := stream.V(0)
|
||||||
// 使用普通帧截图时,必须要传截图间隔,除非只截一张
|
// 使用普通帧截图时,必须要传截图间隔,除非只截一张
|
||||||
switch params.FrameType {
|
switch params.FrameType {
|
||||||
case 0: // 关键帧
|
case 0: // 仅关键帧截图
|
||||||
selectFilter := filter.Select("'eq(pict_type,I)'")
|
selectFilter := filter.Select("'eq(pict_type,I)'")
|
||||||
filters = append(filters, selectFilter)
|
filters = append(filters, selectFilter)
|
||||||
lastFilter = selectFilter
|
lastFilter = selectFilter
|
||||||
outputOptions = append(outputOptions, output.VSync("vfr"))
|
outputOptions = append(outputOptions, output.VSync("vfr"))
|
||||||
case 1:
|
case 1: // 等间隔截图
|
||||||
if params.Num != 1 {
|
if params.Num != 1 {
|
||||||
if params.IntervalFrames > 0 {
|
if params.IntervalFrames > 0 {
|
||||||
selectFilter := filter.Select(fmt.Sprintf("'not(mod(n,%d))'", params.IntervalFrames))
|
selectFilter := filter.Select(fmt.Sprintf("'not(mod(n,%d))'", params.IntervalFrames))
|
||||||
@@ -72,6 +73,17 @@ func (ss *Snapshot) Simple(ctx context.Context, params *SnapshotParams) error {
|
|||||||
lastFilter = fpsFilter
|
lastFilter = fpsFilter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case 2: // 指定帧序列截图
|
||||||
|
if len(params.Frames) > 0 {
|
||||||
|
selectExpr := fmt.Sprintf("'%s'",
|
||||||
|
strings.Join(sugar.Map(params.Frames, func(frame int32) string {
|
||||||
|
return fmt.Sprintf("eq(n,%d)", frame)
|
||||||
|
}), "+"))
|
||||||
|
selectFilter := filter.Select(selectExpr)
|
||||||
|
filters = append(filters, selectFilter)
|
||||||
|
lastFilter = selectFilter
|
||||||
|
outputOptions = append(outputOptions, output.VSync("vfr"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if params.Width > 0 || params.Height > 0 {
|
if params.Width > 0 || params.Height > 0 {
|
||||||
scaleFilter := filter.Scale(params.Width, params.Height).Use(lastFilter)
|
scaleFilter := filter.Scale(params.Width, params.Height).Use(lastFilter)
|
||||||
|
@@ -3,11 +3,19 @@ package liv
|
|||||||
type SnapshotParams struct {
|
type SnapshotParams struct {
|
||||||
Infile string
|
Infile string
|
||||||
Outfile string
|
Outfile string
|
||||||
StartTime float32
|
|
||||||
|
// 0-仅关键帧截图 1-等间隔截图 2-指定帧序列截图
|
||||||
|
FrameType int32 // 截图类型
|
||||||
|
|
||||||
|
// 等间隔截图
|
||||||
Interval int32 // 间隔时间
|
Interval int32 // 间隔时间
|
||||||
IntervalFrames int32 // 间隔帧数
|
IntervalFrames int32 // 间隔帧数
|
||||||
Num int32
|
|
||||||
FrameType int32 // 0-仅关键帧 1-指定时间点的帧
|
// 指定帧序列截图
|
||||||
|
Frames []int32 // 帧序列
|
||||||
|
|
||||||
|
StartTime float32 // 截图开始时间。截图类型为指定帧序列截图时不建议使用此参数
|
||||||
|
Num int32 // 截图最大数量
|
||||||
Width int32
|
Width int32
|
||||||
Height int32
|
Height int32
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user