github.com/amitbet/vnc2video@v0.0.0-20190616012314-9d50b9dab1d9/encoders/qtrle-enc.go (about)

     1  package encoders
     2  
     3  import (
     4  	"errors"
     5  	"image"
     6  	"io"
     7  	"os"
     8  	"os/exec"
     9  	"strings"
    10  	"github.com/amitbet/vnc2video/logger"
    11  )
    12  
    13  // QTRLEImageEncoder quick time rle is an efficient loseless codec, uses .mov extension
    14  type QTRLEImageEncoder struct {
    15  	FFMpegBinPath string
    16  	cmd           *exec.Cmd
    17  	input         io.WriteCloser
    18  	closed        bool
    19  	Framerate     int
    20  }
    21  
    22  func (enc *QTRLEImageEncoder) Init(videoFileName string) {
    23  	fileExt := ".mov"
    24  	if enc.Framerate == 0 {
    25  		enc.Framerate = 12
    26  	}
    27  	if !strings.HasSuffix(videoFileName, fileExt) {
    28  		videoFileName = videoFileName + fileExt
    29  	}
    30  	//binary := "./ffmpeg"
    31  	cmd := exec.Command(enc.FFMpegBinPath,
    32  		"-f", "image2pipe",
    33  		"-vcodec", "ppm",
    34  		//"-r", strconv.Itoa(framerate),
    35  		"-r", "12",
    36  
    37  		//"-re",
    38  		//"-i", "pipe:0",
    39  		"-an", //no audio
    40  		//"-vsync", "2",
    41  		///"-probesize", "10000000",
    42  		"-y",
    43  
    44  		"-i", "-",
    45  		//"–s", "640×360",
    46  		"-vcodec", "qtrle", //"libvpx",//"libvpx-vp9"//"libx264"
    47  		//"-b:v", "0.33M",
    48  		"-threads", "7",
    49  		///"-coder", "1",
    50  		///"-bf", "0",
    51  		///"-me_method", "hex",
    52  		//"-speed", "0",
    53  		//"-lossless", "1", //for vpx
    54  		// "-an", "-f", "webm",
    55  		"-preset", "veryfast",
    56  		//"-tune", "animation",
    57  		"-maxrate", "0.5M",
    58  		"-bufsize", "50M",
    59  		"-g", "250",
    60  
    61  		//"-crf", "0", //for lossless encoding!!!!
    62  
    63  		//"-rc_lookahead", "16",
    64  		//"-profile", "0",
    65  		"-crf", "34",
    66  		//"-qmax", "51",
    67  		//"-qmin", "7",
    68  		//"-slices", "4",
    69  		//"-vb", "2M",
    70  
    71  		videoFileName,
    72  	)
    73  	//cmd := exec.Command("/bin/echo")
    74  
    75  	//io.Copy(cmd.Stdout, os.Stdout)
    76  	cmd.Stdout = os.Stdout
    77  	cmd.Stderr = os.Stderr
    78  
    79  	encInput, err := cmd.StdinPipe()
    80  	enc.input = encInput
    81  	if err != nil {
    82  		logger.Error("can't get ffmpeg input pipe")
    83  	}
    84  	enc.cmd = cmd
    85  }
    86  func (enc *QTRLEImageEncoder) Run(videoFileName string) error {
    87  	if _, err := os.Stat(enc.FFMpegBinPath); os.IsNotExist(err) {
    88  		if _, err := os.Stat(enc.FFMpegBinPath + ".exe"); os.IsNotExist(err) {
    89  			logger.Error("encoder file doesn't exist in path:", enc.FFMpegBinPath)
    90  			return errors.New("encoder file doesn't exist in path" + videoFileName)
    91  		} else {
    92  			enc.FFMpegBinPath = enc.FFMpegBinPath + ".exe"
    93  		}
    94  	}
    95  
    96  	enc.Init(videoFileName)
    97  	logger.Debugf("launching binary: %v", enc.cmd)
    98  	err := enc.cmd.Run()
    99  	if err != nil {
   100  		logger.Errorf("error while launching ffmpeg: %v\n err: %v", enc.cmd.Args, err)
   101  		return err
   102  	}
   103  	return nil
   104  }
   105  func (enc *QTRLEImageEncoder) Encode(img image.Image) {
   106  	if enc.input == nil || enc.closed {
   107  		return
   108  	}
   109  
   110  	err := encodePPM(enc.input, img)
   111  	if err != nil {
   112  		logger.Error("error while encoding image:", err)
   113  	}
   114  }
   115  
   116  func (enc *QTRLEImageEncoder) Close() {
   117  	enc.closed = true
   118  	//enc.cmd.Process.Kill()
   119  }