@@ -28,6 +28,8 @@ type Options struct {
2828 MaxSessions int
2929 TempDir string
3030 FFmpegPath string
31+ HardwareDecode string
32+ HardwareDevice string
3133 BufferPauseThreshold time.Duration
3234 BufferResumeThreshold time.Duration
3335 BufferCheckInterval time.Duration
@@ -123,8 +125,16 @@ func NewManager(options Options) *Manager {
123125 if options .RestartGraceTimeout <= 0 {
124126 options .RestartGraceTimeout = defaultRestartGraceTimeout
125127 }
128+ options .HardwareDecode = strings .ToLower (strings .TrimSpace (options .HardwareDecode ))
129+ options .HardwareDevice = strings .TrimSpace (options .HardwareDevice )
126130 if options .Runner == nil && options .FFmpegPath != "" {
127- options .Runner = FFmpegRunner {Path : options .FFmpegPath }
131+ options .Runner = FFmpegRunner {
132+ Path : options .FFmpegPath ,
133+ Options : FFmpegOptions {
134+ HardwareDecode : options .HardwareDecode ,
135+ HardwareDevice : options .HardwareDevice ,
136+ },
137+ }
128138 }
129139 return & Manager {options : options , sessions : map [string ]* Session {}, media : map [string ]MediaInfo {}}
130140}
@@ -662,15 +672,21 @@ func durationToTicks(d time.Duration) int64 {
662672}
663673
664674type FFmpegRunner struct {
665- Path string
675+ Path string
676+ Options FFmpegOptions
677+ }
678+
679+ type FFmpegOptions struct {
680+ HardwareDecode string
681+ HardwareDevice string
666682}
667683
668684func (r FFmpegRunner ) Start (ctx context.Context , session * Session , request Request ) (Process , error ) {
669685 if r .Path == "" {
670686 return nil , errors .New ("ffmpeg path is required" )
671687 }
672688
673- args := buildFFmpegArgs (session , request )
689+ args := buildFFmpegArgs (session , request , r . Options )
674690 playlist := filepath .Join (session .Dir , "master.m3u8" )
675691 logPath := filepath .Join (session .Dir , "ffmpeg.log" )
676692 logging .Infof ("transcode start id=%s segment=%d" , session .ID , session .SegmentStartIndex )
@@ -708,16 +724,21 @@ func (r FFmpegRunner) Start(ctx context.Context, session *Session, request Reque
708724 return process , nil
709725}
710726
711- func buildFFmpegArgs (session * Session , request Request ) []string {
727+ func buildFFmpegArgs (session * Session , request Request , options ... FFmpegOptions ) []string {
712728 playlist := filepath .Join (session .Dir , "master.m3u8" )
713729 segmentPattern := filepath .Join (session .Dir , "segment_%05d.ts" )
730+ ffmpegOptions := FFmpegOptions {}
731+ if len (options ) > 0 {
732+ ffmpegOptions = options [0 ]
733+ }
714734 args := []string {
715735 "-hide_banner" ,
716736 "-loglevel" , "info" ,
717737 }
718738 if headerText := ffmpegHeaders (request .Headers ); headerText != "" {
719739 args = append (args , "-headers" , headerText )
720740 }
741+ args = appendHardwareDecodeArgs (args , ffmpegOptions )
721742 if session .StartTimeTicks > 0 {
722743 args = append (args , "-ss" , ticksSeconds (session .StartTimeTicks ))
723744 }
@@ -751,6 +772,21 @@ func buildFFmpegArgs(session *Session, request Request) []string {
751772 return args
752773}
753774
775+ func appendHardwareDecodeArgs (args []string , options FFmpegOptions ) []string {
776+ switch strings .ToLower (strings .TrimSpace (options .HardwareDecode )) {
777+ case "" , "none" , "off" , "false" :
778+ return args
779+ case "vaapi" :
780+ args = append (args , "-hwaccel" , "vaapi" )
781+ if device := strings .TrimSpace (options .HardwareDevice ); device != "" {
782+ args = append (args , "-hwaccel_device" , device )
783+ }
784+ return args
785+ default :
786+ return args
787+ }
788+ }
789+
754790func ticksSeconds (ticks int64 ) string {
755791 return strconv .FormatFloat (float64 (ticks )/ 10_000_000 , 'f' , 6 , 64 )
756792}
0 commit comments