Beispiel #1
0
func (m *mp4Handler) RequestHandle(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	// Handle only GET requests with ContentLength of 0 without a Range header
	if r.Method != "GET" || len(r.Header.Get("Range")) > 0 || r.ContentLength > 0 {
		m.next.RequestHandle(ctx, w, r)
		return
	}

	// parse the request
	var start, err = strconv.Atoi(r.URL.Query().Get(startKey))
	if err != nil || 0 >= start { // that start is not ok
		m.next.RequestHandle(ctx, w, r)
		return
	}
	var startTime = time.Duration(start) * time.Second
	var newreq = copyRequest(r)
	removeQueryArgument(newreq.URL, startKey)
	var header = make(http.Header)
	var rr = &rangeReader{
		ctx:      ctx,
		req:      copyRequest(newreq),
		location: m.loc,
		next:     m.next,
		callback: func(frw *httputils.FlexibleResponseWriter) bool {
			if len(header) == 0 {
				httputils.CopyHeadersWithout(frw.Header(), header, skipHeaders...)
			} else {
				return frw.Header().Get("Last-Modified") == header.Get("Last-Modified")
			}
			return true
		},
	}
	var video *mp4.MP4
	video, err = mp4.Decode(rr)
	if err != nil {
		m.loc.Logger.Errorf("error from the mp4.Decode - %s", err)
		m.next.RequestHandle(ctx, w, r)
		return
	}
	if video == nil || video.Moov == nil { // missing something?
		m.next.RequestHandle(ctx, w, r)
		return
	}

	cl, err := clip.New(video, startTime, rr)
	if err != nil {
		m.loc.Logger.Errorf("error while clipping a video(%+v) - %s", video, err)
		m.next.RequestHandle(ctx, w, r)
		return
	}
	httputils.CopyHeaders(header, w.Header())
	w.Header().Set("Content-Length", strconv.FormatUint(cl.Size(), 10))
	size, err := cl.WriteTo(w)
	m.loc.Logger.Debugf("wrote %d", size)
	if err != nil {
		m.loc.Logger.Logf("error on writing the clip response - %s", err)
	}
	if uint64(size) != cl.Size() {
		m.loc.Logger.Debugf("handler.mp4[%p]: expected to write %d but wrote %d", m, cl.Size(), size)
	}
}
Beispiel #2
0
func main() {
	go func() {
		fmt.Println(http.ListenAndServe(":6060", nil))
	}()

	cmd := cli.App("mp4tool", "MP4 command line tool")

	cmd.Command("info", "Displays information about a media", func(cmd *cli.Cmd) {
		file := cmd.StringArg("FILE", "", "the file to display")
		cmd.Action = func() {
			rr := &fileRangeReader{fileName: *file}
			v, err := mp4.Decode(rr)
			if err != nil {
				fmt.Println(err)
			}
			v.Dump()
		}
	})

	cmd.Command("clip", "Generates a clip", func(cmd *cli.Cmd) {
		start := cmd.IntOpt("s start", 0, "start time (sec)")
		src := cmd.StringArg("SRC", "", "the source file name")
		dst := cmd.StringArg("DST", "", "the destination file name")
		cmd.Action = func() {
			rr := &fileRangeReader{fileName: *src}
			v, err := mp4.Decode(rr)
			if err != nil {
				fmt.Println(err)
				return
			}
			out, err := os.Create(*dst)
			if err != nil {
				fmt.Println(err)
				return
			}
			defer closeWithPrintingError(out, "error on closing output file")
			clip, err := clip.New(v, time.Duration(*start)*time.Second, rr)
			if err != nil {
				fmt.Println(err)
				return
			}
			fmt.Scanln()
			size, err := clip.WriteTo(out)
			if err != nil {
				fmt.Println(err)
			}
			fmt.Println("wrote", size)
		}
	})

	cmd.Command("copy", "Decodes a media and reencodes it to another file", func(cmd *cli.Cmd) {
		src := cmd.StringArg("SRC", "", "the source file name")
		dst := cmd.StringArg("DST", "", "the destination file name")
		cmd.Action = func() {
			rr := &fileRangeReader{fileName: *src}
			v, err := mp4.Decode(rr)
			if err != nil {
				fmt.Println(err)
				return
			}
			out, err := os.Create(*dst)
			if err != nil {
				fmt.Println(err)
				return
			}
			defer closeWithPrintingError(out, "error on closing output file")
			if err := v.Encode(out); err != nil {
				fmt.Println("error on encoding", err)
			}
		}
	})
	if err := cmd.Run(os.Args); err != nil {
		fmt.Println("error form cmd.Run", err)
	}
	fmt.Println("press return to exit the program")
	fmt.Scanln()
}