Пример #1
0
//Creating a thumbnail from a mp4 is complex so I cheat and use FFMPEG to create a JPEG...
//JPEG is straightforwards
// but ffmpeg probably can't make a thumbnail from a piped reader, so this only works if our
//ReadSeeker is actually an *os.File
func (m *Mp4Video) Thumbnail(in io.ReadSeeker, longSide int) (io.ReadSeeker, string, error) {
	var cmd *exec.Cmd
	if file, ok := in.(*os.File); ok {
		//this is the best way as ffmpeg can seek.
		cmd = exec.Command("ffmpeg", "-i", "/dev/fd/3", "-vframes", "1", "-f", "image2", "-")
		cmd.ExtraFiles = []*os.File{file}
	} else {
		log.Println("mp4thumb: using stdin (will probably fail...)")
		cmd = exec.Command("ffmpeg", "-i", "-", "-vframes", "1", "-f", "image2", "-")
		cmd.Stdin = in
	}
	stdout, err := cmd.StdoutPipe()
	//cmd.Stderr = os.Stderr
	if err != nil {
		return nil, "", err
	}
	if err := cmd.Start(); err != nil {
		return nil, "", err
	}
	img, err := jpeg.Decode(stdout)
	if err != nil {
		return nil, "", err
	}
	if err := cmd.Wait(); err != nil {
		return nil, "", err
	}
	//now we should have a jpeg to resize!
	var w, h int
	aspect := float64(m.Width) / float64(m.Height)
	if m.Width > m.Height {
		w, h = longSide, int(float64(longSide)/aspect)
	} else {
		w, h = int(float64(longSide)*aspect), longSide
	}
	switch m.Orientation {
	case photo.OrientedNormal90, photo.OrientedNormal270:
		//flip then rotate 270
		w, h = h, w
	}
	//now create thumbnail.
	img = imaging.Thumbnail(img, w, h, imaging.Box)
	//rotate if needed.
	switch m.Orientation {
	case photo.OrientedNormal90:
		//rotate 90 (270 anticlockwise)
		img = imaging.Rotate270(img)
	case photo.OrientedNormal180:
		//rotate 180
		img = imaging.Rotate180(img)
	case photo.OrientedNormal270:
		//rotate 270 (90 anti-clockwise)
		img = imaging.Rotate90(img)
	}
	var wr bytes.Buffer
	err = jpeg.Encode(&wr, img, nil)
	return bytes.NewReader(wr.Bytes()), "image/jpeg", err
}
Пример #2
0
func (w *Wirer) Wire(cmd *exec.Cmd) (*os.File, *os.File, *os.File, *os.File, error) {
	extraFdR, extraFdW, err := os.Pipe()
	if err != nil {
		return nil, nil, nil, nil, err
	}
	cmd.ExtraFiles = []*os.File{extraFdR}

	var stdinW, stdoutR, stderrR *os.File
	if w.WithTty {
		cmd.Stdin, stdinW, stdoutR, cmd.Stdout, stderrR, cmd.Stderr, err = createTtyPty(w.WindowColumns, w.WindowRows)
		cmd.SysProcAttr.Setctty = true
		cmd.SysProcAttr.Setsid = true
	} else {
		cmd.Stdin, stdinW, stdoutR, cmd.Stdout, stderrR, cmd.Stderr, err = createPipes()
	}

	return stdinW, stdoutR, stderrR, extraFdW, nil
}
Пример #3
0
func setupCommMapping(cmd *exec.Cmd, comm *Mapping, rOut, wIn *os.File) {
	cmd.ExtraFiles = append(cmd.ExtraFiles, comm.f)
	cmd.ExtraFiles = append(cmd.ExtraFiles, rOut)
	cmd.ExtraFiles = append(cmd.ExtraFiles, wIn)
}
Пример #4
0
func (d *ExecRunner) Run(log lager.Logger, spec *runrunc.PreparedSpec, processesPath, handle string, tty *garden.TTYSpec, pio garden.ProcessIO) (p garden.Process, theErr error) {
	log = log.Session("execrunner")

	log.Info("start")
	defer log.Info("done")

	processID := d.processIDGen.Generate()

	processPath := filepath.Join(processesPath, processID)
	if err := os.MkdirAll(processPath, 0700); err != nil {
		return nil, err
	}

	fd3r, fd3w, err := os.Pipe()
	if err != nil {
		return nil, err
	}

	logr, logw, err := os.Pipe()
	if err != nil {
		return nil, err
	}

	syncr, syncw, err := os.Pipe()
	if err != nil {
		return nil, err
	}

	defer fd3r.Close()
	defer logr.Close()
	defer syncr.Close()

	process := newProcess(processID, processPath, filepath.Join(processPath, "pidfile"), d.pidGetter)
	process.mkfifos()
	if err != nil {
		return nil, err
	}

	var cmd *exec.Cmd
	if tty != nil {
		var rows, cols int
		if tty.WindowSize != nil {
			rows = tty.WindowSize.Rows
			cols = tty.WindowSize.Columns
		}

		cmd = exec.Command(d.dadooPath, "-tty", "-rows", strconv.Itoa(rows), "-cols", strconv.Itoa(cols), "-uid", strconv.Itoa(spec.HostUID), "-gid", strconv.Itoa(spec.HostGID), "exec", d.runcPath, processPath, handle)
	} else {
		cmd = exec.Command(d.dadooPath, "exec", d.runcPath, processPath, handle)
	}

	cmd.ExtraFiles = []*os.File{
		fd3w,
		logw,
		syncw,
	}

	encodedSpec, err := json.Marshal(spec.Process)
	if err != nil {
		return nil, err // this could *almost* be a panic: a valid spec should always encode (but out of caution we'll error)
	}

	cmd.Stdin = bytes.NewReader(encodedSpec)
	if err := d.commandRunner.Start(cmd); err != nil {
		return nil, err
	}
	go d.commandRunner.Wait(cmd) // wait on spawned process to avoid zombies

	fd3w.Close()
	logw.Close()
	syncw.Close()

	stdin, stdout, stderr, err := process.openPipes(pio)
	if err != nil {
		return nil, err
	}

	syncMsg := make([]byte, 1)
	_, err = syncr.Read(syncMsg)
	if err != nil {
		return nil, err
	}

	process.streamData(pio, stdin, stdout, stderr)
	defer func() {
		theErr = processLogs(log, logr, theErr)
	}()

	log.Info("read-exit-fd")
	runcExitStatus := make([]byte, 1)
	fd3r.Read(runcExitStatus)
	log.Info("runc-exit-status", lager.Data{"status": runcExitStatus[0]})
	if runcExitStatus[0] != 0 {
		return nil, fmt.Errorf("exit status %d", runcExitStatus[0])
	}

	return process, nil
}
Пример #5
0
func startInstance(cmd *exec.Cmd, r *os.File, w *os.File) error {
	cmd.ExtraFiles = []*os.File{r, w}
	return cmd.Start()
}