Пример #1
0
func GetFlvLiveAddress(cmd string, subCmd string) {
	if len(os.Args) < 4 {
		CmdHelp(cmd, subCmd)
		return
	}

	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)

	streamId := os.Args[3]

	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		fmt.Println("Get stream error,", gErr)
		return
	}

	flvLiveUrls, gErr := stream.HttpFlvLiveUrls()
	if gErr != nil {
		fmt.Println("Get flv live urls error,", gErr)
		return
	}

	for tag, liveUrl := range flvLiveUrls {
		fmt.Println(tag, liveUrl)
	}
}
Пример #2
0
func EnableStream(cmd string, subCmd string) {
	if len(os.Args) < 4 {
		CmdHelp(cmd, subCmd)
		return
	}

	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)

	streamId := os.Args[3]

	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		fmt.Println("Get stream error,", gErr)
		return
	}

	_, dErr := stream.Enable()
	if dErr != nil {
		fmt.Println("Enable stream error,", dErr)
		return
	}
	fmt.Println("Done!")
}
Пример #3
0
func GetRtmpPubAddress(cmd string, subCmd string) {
	if len(os.Args) < 4 {
		CmdHelp(cmd, subCmd)
		return
	}

	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)

	streamId := os.Args[3]

	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		fmt.Println("Get stream error,", gErr)
		return
	}

	rmptPubUrl := stream.RtmpPublishUrl()
	fmt.Println(rmptPubUrl)
}
Пример #4
0
func GetLivePlayUrl(streamId string) (livePlayUrls map[string]string, err error) {
	crendentials := pili.NewCredentials(config.App.AccessKey, config.App.SecretKey)
	hub := pili.NewHub(crendentials, config.App.LiveHub)
	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		err = errors.New(fmt.Sprintf("get live stream error, %s", gErr.Error()))
		return
	}
	livePlayUrls, err = stream.RtmpLiveUrls()
	return
}
Пример #5
0
func GetPlaybackUrl(streamId string, startTime, endTime int64) (playbackUrls map[string]string, err error) {
	crendentials := pili.NewCredentials(config.App.AccessKey, config.App.SecretKey)
	hub := pili.NewHub(crendentials, config.App.LiveHub)
	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		err = errors.New(fmt.Sprintf("get live stream error, %s", gErr.Error()))
		return
	}

	playbackUrls, err = stream.HlsPlaybackUrls(startTime, endTime)
	return
}
Пример #6
0
//create a new stream
func CreateStream(cmd string, subCmd string) {
	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)

	flagSet := flag.NewFlagSet(subCmd, flag.ExitOnError)
	flagSet.Usage = func() {
		CmdHelp(cmd, subCmd)
	}

	var title string
	var publishKey string
	var publishSecurity string

	flagSet.StringVar(&title, "t", "", "title")
	flagSet.StringVar(&publishKey, "pbk", "", "publish key")
	flagSet.StringVar(&publishSecurity, "pbs", "", "publish security")

	flagSet.Parse(os.Args[3:])

	if publishSecurity != "" {
		if !(publishSecurity == "static" || publishSecurity == "dynamic") {
			fmt.Println("Publish Security can only be 'static' or 'dynamic'")
			return
		}
	}

	options := pili.OptionalArguments{
		Title:           title,
		PublishKey:      publishKey,
		PublishSecurity: publishSecurity,
	}

	stream, cErr := hub.CreateStream(options)
	if cErr != nil {
		fmt.Println("Create stream error,", cErr)
		return
	}

	jsonStr, jsonErr := stream.ToJSONString()
	if jsonErr != nil {
		fmt.Println("Create stream error,", jsonErr)
		return
	}

	fmt.Println(jsonStr)
}
Пример #7
0
func main() {
	credentials := pili.NewCredentials(ACCESS_KEY, SECRET_KEY)
	hub := pili.NewHub(credentials, HUB_NAME)

	options := pili.OptionalArguments{ // optional
		Title:           "", // optional, auto-generated as default
		PublishKey:      "", // optional, auto-generated as default
		PublishSecurity: "", // optional, can be "dynamic" or "static", "dynamic" as default
	}
	stream, err := hub.CreateStream(options)
	if err != nil {
		fmt.Println("Error:", err)
	}
	fmt.Println("CreateStream:\n", stream)
}
Пример #8
0
//@param streamId
//@return rtmp, hls, flv live play urls
func GetLivePlayUrls(streamId string) (livePlayUrls map[string]string, err error) {
	crendentials := pili.NewCredentials(config.App.AccessKey, config.App.SecretKey)
	hub := pili.NewHub(crendentials, config.App.LiveHub)
	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		err = errors.New(fmt.Sprintf("get live stream error, %s", gErr.Error()))
		return
	}

	livePlayUrls = make(map[string]string)

	rtmpLivePlayUrls, gErr := stream.RtmpLiveUrls()
	if gErr != nil {
		err = errors.New(fmt.Sprintf("get live stream rtmp play url error, %s", gErr.Error()))
		return
	}

	hlsLivePlayUrls, gErr := stream.HlsLiveUrls()
	if gErr != nil {
		err = errors.New(fmt.Sprintf("get live stream hls play url error, %s", gErr.Error()))
		return
	}

	flvLivePlayUrls, gErr := stream.HttpFlvLiveUrls()
	if gErr != nil {
		err = errors.New(fmt.Sprintf("get live stream flv play url error, %s", gErr.Error()))
		return
	}

	if v, ok := rtmpLivePlayUrls["ORIGIN"]; ok {
		livePlayUrls["RTMP"] = v
	}

	if v, ok := hlsLivePlayUrls["ORIGIN"]; ok {
		livePlayUrls["HLS"] = v
	}

	if v, ok := flvLivePlayUrls["ORIGIN"]; ok {
		livePlayUrls["FLV"] = v
	}

	return
}
Пример #9
0
//create stream
//@return streamId, stream, err
func CreateDynamicStream() (streamId string, streamData string, err error) {
	crendentials := pili.NewCredentials(config.App.AccessKey, config.App.SecretKey)
	hub := pili.NewHub(crendentials, config.App.LiveHub)
	options := pili.OptionalArguments{
		PublishSecurity: "dynamic",
	}
	stream, cErr := hub.CreateStream(options)
	if cErr != nil {
		err = errors.New(fmt.Sprintf("create live stream error, %s", cErr.Error()))
		return
	}

	streamJson, tErr := stream.ToJSONString()
	if tErr != nil {
		err = errors.New("marshal live stream error")
		return
	}

	streamData = streamJson
	streamId = stream.Id

	return
}
Пример #10
0
//get stream
//@param stream id
//@return stream, code,err
//if code==404, try to create a new stream
func GetStream(streamId string) (streamData string, code int, err error) {
	crendentials := pili.NewCredentials(config.App.AccessKey, config.App.SecretKey)
	hub := pili.NewHub(crendentials, config.App.LiveHub)
	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		if v, ok := gErr.(*pili.ErrorInfo); ok {
			err = fmt.Errorf("get live stream error, %s", v.Message)
			code = v.ErrCode
		} else {
			err = fmt.Errorf("get live stream error, %s", gErr.Error())
		}
		return
	}

	streamJson, tErr := stream.ToJSONString()
	if tErr != nil {
		err = fmt.Errorf("get live stream error, parse error %s", tErr.Error())
		return
	}

	streamData = streamJson
	return
}
Пример #11
0
//get stream info
func GetStream(cmd string, subCmd string) {
	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	streamId := os.Args[3]
	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)
	stream, sErr := hub.GetStream(streamId)
	if sErr != nil {
		fmt.Println("Get stream error,", sErr)
		return
	}

	jsonStr, jsonErr := stream.ToJSONString()
	if jsonErr != nil {
		fmt.Println("Get stream error,", jsonErr)
		return
	}

	fmt.Println(jsonStr)
}
Пример #12
0
func v1() {
	credentials := pili.NewCredentials(ACCESS_KEY, SECRET_KEY)
	Hub = pili.NewHub(credentials, HUB_V1_NAME)

	router := gin.Default()
	router.Static("/assets", "./assets")
	router.LoadHTMLGlob("templates/*")

	// Stream list
	router.GET("/", func(c *gin.Context) {
		options := pili.OptionalArguments{
			Status: "connected",
			Marker: "",
			Limit:  100,
		}
		listResult, err := Hub.ListStreams(options)
		if err != nil {
			c.HTML(400, "error.tmpl", gin.H{"error": err})
			c.Abort()
			return
		}
		c.HTML(200, "index.tmpl", gin.H{
			"streams": listResult.Items,
		})
	})

	// Player
	router.GET("/player", func(c *gin.Context) {
		streamId := c.Query("stream")
		stream, err := Hub.GetStream(streamId)
		if err != nil {
			c.HTML(400, "error.tmpl", gin.H{"error": err})
			c.Abort()
			return
		}

		liveRtmpUrls, err := stream.RtmpLiveUrls()
		if err != nil {
			fmt.Println("Error:", err)
			c.HTML(400, "error.tmpl", gin.H{"error": err})
			c.Abort()
			return
		}

		liveHlsUrls, err := stream.HlsLiveUrls()
		if err != nil {
			fmt.Println("Error:", err)
			c.HTML(400, "error.tmpl", gin.H{"error": err})
			c.Abort()
			return
		}

		liveHdlUrls, err := stream.HttpFlvLiveUrls()
		if err != nil {
			fmt.Println("Error:", err)
			c.HTML(400, "error.tmpl", gin.H{"error": err})
			c.Abort()
			return
		}

		c.HTML(200, "player.tmpl", gin.H{
			"stream":      stream,
			"liveRtmpUrl": liveRtmpUrls["ORIGIN"],
			"liveHlsUrl":  liveHlsUrls["ORIGIN"],
			"liveHdlUrl":  liveHdlUrls["ORIGIN"],
		})
	})

	// // Publisher
	// router.GET("/publisher", func(c *gin.Context) {

	// 	c.HTML(200, "pubisher.tmpl", gin.H{
	// 		"stream":      stream,
	// 		"liveRtmpUrl": liveRtmpUrls["ORIGIN"],
	// 		"liveHlsUrl":  liveHlsUrls["ORIGIN"],
	// 		"liveHdlUrl":  liveHdlUrls["ORIGIN"],
	// 	})
	// }

	// API
	router.POST("/api/stream", func(c *gin.Context) {
		options := pili.OptionalArguments{
			PublishSecurity: "static",
		}
		stream, err := Hub.CreateStream(options)
		if err != nil {
			c.String(400, err.Error())
			c.Abort()
			return
		}
		streamJson, err := stream.ToJSONString()
		if err != nil {
			c.String(400, err.Error())
			c.Abort()
			return
		}
		c.String(200, streamJson)
	})

	// API
	// "/api/stream/z1.abclive.5633b990eb6f9213a2002473/status"
	router.GET("/api/stream/:id/status", func(c *gin.Context) {
		id := c.Params.ByName("id")

		stream, err := Hub.GetStream(id)
		if err != nil {
			c.JSON(400, err)
			c.Abort()
			return
		}

		streamStatus, err := stream.Status()
		if err != nil {
			c.JSON(400, err)
			c.Abort()
			return
		}
		c.JSON(200, streamStatus)
	})

	// API
	router.POST("/api/stream/:id", func(c *gin.Context) {
		id := c.Params.ByName("id")
		options := pili.OptionalArguments{
			Title:           id,
			PublishSecurity: "static",
		}
		stream, err := Hub.CreateStream(options)
		if err != nil {
			stream, err = Hub.GetStream("z1." + HUB_V1_NAME + "." + id)
			if err != nil {
				c.JSON(400, err)
				c.Abort()
				return
			}
		}
		streamJson, err := stream.ToJSONString()
		if err != nil {
			fmt.Println(err)
			c.String(400, err.Error())
			c.Abort()
			return
		}
		c.String(200, streamJson)
	})

	// API
	router.GET("/api/stream/:id/play", func(c *gin.Context) {
		id := c.Params.ByName("id")
		stream, err := Hub.GetStream("z1." + HUB_V1_NAME + "." + id)
		if err != nil {
			c.JSON(400, err)
			c.Abort()
			return
		}

		liveRtmpUrls, err := stream.RtmpLiveUrls()
		if err != nil {
			c.JSON(400, err)
			c.Abort()
			return
		}

		c.String(200, liveRtmpUrls["ORIGIN"])
	})

	// Listen and server on 0.0.0.0:8080
	router.Run(":8080")
}
Пример #13
0
//list streams
func ListStream(cmd string, subCmd string) {
	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)

	flagSet := flag.NewFlagSet(subCmd, flag.ExitOnError)
	flagSet.Usage = func() {
		CmdHelp(cmd, subCmd)
	}

	var status string
	var marker string
	var limit int
	var prefix string

	flagSet.StringVar(&status, "s", "", "stream status")
	flagSet.StringVar(&marker, "m", "", "list offset marker")
	flagSet.IntVar(&limit, "l", 0, "limit count")
	flagSet.StringVar(&prefix, "p", "", "title prefix")

	flagSet.Parse(os.Args[3:])

	options := pili.OptionalArguments{
		Status: status,
		Marker: marker,
		Limit:  uint(limit),
		Title:  prefix,
	}

	maxRetries := 5

	fCnt := 0

	for {
		listResult, lErr := hub.ListStreams(options)
		if lErr != nil {
			fmt.Println("List stream error,", lErr)
			if maxRetries > 0 {
				fmt.Println("Retrying...")
				maxRetries -= 1
				continue
			} else {
				break
			}
		}

		for _, item := range listResult.Items {
			fmt.Println(fmt.Sprintf("%s\t%s\t%s\t%s", item.Id, item.Title, item.PublishKey, item.PublishSecurity))
		}

		fCnt += len(listResult.Items)

		if (limit > 0 && fCnt >= limit) || listResult.End {
			break
		}

		options.Marker = listResult.Marker
		//reset
		maxRetries = 5
	}
}
Пример #14
0
//@param start 20151202102000
//@param end
func GetHlsPlayAddress(cmd string, subCmd string) {
	if len(os.Args) < 4 {
		CmdHelp(cmd, subCmd)
		return
	}

	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)

	streamId := os.Args[3]
	flagSet := flag.NewFlagSet(subCmd, flag.ExitOnError)
	flagSet.Usage = func() {
		CmdHelp(cmd, subCmd)
	}

	var startTime string
	var endTime string

	flagSet.StringVar(&startTime, "s", "", "start time")
	flagSet.StringVar(&endTime, "e", "", "end time")

	flagSet.Parse(os.Args[4:])

	if startTime == "" || endTime == "" {
		CmdHelp(cmd, subCmd)
		return
	}

	var start int64
	var end int64
	var pErr error

	if start, pErr = parseTime(startTime); pErr != nil {
		CmdHelp(cmd, subCmd)
		return
	}

	if end, pErr = parseTime(endTime); pErr != nil {
		CmdHelp(cmd, subCmd)
		return
	}

	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		fmt.Println("Get stream error,", gErr)
		return
	}

	hlsPlayUrls, gErr := stream.HlsPlaybackUrls(start, end)
	if gErr != nil {
		fmt.Println("Get hls playback urls error,", gErr)
		return
	}

	for tag, playUrl := range hlsPlayUrls {
		fmt.Println(tag, playUrl)
	}

}
Пример #15
0
func UpdateStream(cmd string, subCmd string) {
	if len(os.Args) < 4 {
		CmdHelp(cmd, subCmd)
		return
	}

	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)

	streamId := os.Args[3]
	flagSet := flag.NewFlagSet(subCmd, flag.ExitOnError)
	flagSet.Usage = func() {
		CmdHelp(cmd, subCmd)
	}

	var publishKey string
	var publishSecurity string

	flagSet.StringVar(&publishKey, "pbk", "", "publish key")
	flagSet.StringVar(&publishSecurity, "pbs", "", "publish security")

	flagSet.Parse(os.Args[4:])

	if publishKey == "" && publishSecurity == "" {
		CmdHelp(cmd, subCmd)
		return
	}

	if publishSecurity != "" {
		if !(publishSecurity == "static" || publishSecurity == "dynamic") {
			fmt.Println("Publish Security can only be 'static' or 'dynamic'")
			return
		}
	}

	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		fmt.Println("Get stream error,", gErr)
		return
	}

	stream.PublishKey = publishKey
	stream.PublishSecurity = publishSecurity

	nStream, uErr := stream.Update()
	if uErr != nil {
		fmt.Println("Update stream error,", uErr)
		return
	}

	fmt.Println("Updated Stream:")
	fmt.Println()
	fmt.Println(" Stream Id:\t\t", nStream.Id)
	fmt.Println(" Stream Title:\t\t", nStream.Title)
	fmt.Println(" Publish Key:\t\t", nStream.PublishKey)
	fmt.Println(" Publish Security:\t", nStream.PublishSecurity)
}
Пример #16
0
func TakeStreamSnapshot(cmd string, subCmd string) {
	if len(os.Args) < 4 {
		CmdHelp(cmd, subCmd)
		return
	}

	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)

	streamId := os.Args[3]
	flagSet := flag.NewFlagSet(subCmd, flag.ExitOnError)
	flagSet.Usage = func() {
		CmdHelp(cmd, subCmd)
	}

	var name string
	var format string
	var snapshotTime string
	var notifyUrl string

	flagSet.StringVar(&name, "n", "", "name")
	flagSet.StringVar(&format, "f", "", "format")
	flagSet.StringVar(&snapshotTime, "t", "", "snapshot time")
	flagSet.StringVar(&notifyUrl, "c", "", "notify url")

	flagSet.Parse(os.Args[4:])

	if name == "" || format == "" || snapshotTime == "" {
		CmdHelp(cmd, subCmd)
		return
	}

	var shotTime int64
	var pErr error

	if shotTime, pErr = parseTime(snapshotTime); pErr != nil {
		CmdHelp(cmd, subCmd)
		return
	}

	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		fmt.Println("Get stream error,", gErr)
		return
	}

	options := pili.OptionalArguments{
		Time:      shotTime,
		NotifyUrl: notifyUrl,
	}

	ret, sErr := stream.Snapshot(name, format, options)
	if sErr != nil {
		fmt.Println("Snapshot stream error,", sErr)
		return
	}

	fmt.Println("TargetUrl:", ret.TargetUrl)
	fmt.Println()
	fmt.Println(fmt.Sprintf("See http://api.qiniu.com/status/get/prefop?id=%s", ret.PersistentId))
}
Пример #17
0
func SaveStreamAsVideo(cmd string, subCmd string) {
	if len(os.Args) < 4 {
		CmdHelp(cmd, subCmd)
		return
	}

	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)

	streamId := os.Args[3]
	flagSet := flag.NewFlagSet(subCmd, flag.ExitOnError)
	flagSet.Usage = func() {
		CmdHelp(cmd, subCmd)
	}

	var name string
	var format string
	var startTime string
	var endTime string
	var pipeline string
	var notifyUrl string

	flagSet.StringVar(&name, "n", "", "name")
	flagSet.StringVar(&format, "f", "", "format")
	flagSet.StringVar(&startTime, "s", "", "start time")
	flagSet.StringVar(&endTime, "e", "", "end time")
	flagSet.StringVar(&pipeline, "p", "", "pipeline")
	flagSet.StringVar(&notifyUrl, "c", "", "notify url")

	flagSet.Parse(os.Args[4:])

	if name == "" || startTime == "" || endTime == "" {
		CmdHelp(cmd, subCmd)
		return
	}

	if format == "null" {
		format = ""
	}

	var start int64
	var end int64
	var pErr error

	if start, pErr = parseTime(startTime); pErr != nil {
		CmdHelp(cmd, subCmd)
		return
	}

	if end, pErr = parseTime(endTime); pErr != nil {
		CmdHelp(cmd, subCmd)
		return
	}

	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		fmt.Println("Get stream error,", gErr)
		return
	}

	options := pili.OptionalArguments{
		UserPipeline: pipeline,
		NotifyUrl:    notifyUrl,
	}

	ret, sErr := stream.SaveAs(name, format, start, end, options)
	if sErr != nil {
		fmt.Println("Save stream as video error,", sErr)
		return
	}

	fmt.Println("M3u8Url:\t", ret.Url)
	fmt.Println("TargetUrl:\t", ret.TargetUrl)
	fmt.Println()
	fmt.Println(fmt.Sprintf("See http://api.qiniu.com/status/get/prefop?id=%s", ret.PersistentId))
}
Пример #18
0
func GetStreamStatus(cmd string, subCmd string) {
	if len(os.Args) < 4 {
		CmdHelp(cmd, subCmd)
		return
	}

	gErr := liveHub.Get()
	if gErr != nil {
		fmt.Println(gErr)
		return
	}

	cred := pili.NewCredentials(liveHub.AccessKey, liveHub.SecretKey)
	hub := pili.NewHub(cred, liveHub.Hub)

	streamId := os.Args[3]

	stream, gErr := hub.GetStream(streamId)
	if gErr != nil {
		fmt.Println("Get stream error,", gErr)
		return
	}

	platform := runtime.GOOS
	for {

		status, gErr := stream.Status()
		if gErr != nil {
			fmt.Println("Get stream status error,", gErr)
			return
		}

		var outputStatus string

		if platform == "windows" {
			outputStatus += fmt.Sprintf("%s", strings.ToUpper(status.Status))
		} else {
			if status.Status == "connected" {
				outputStatus += fmt.Sprintf("\033[32m%s\033[37m", strings.ToUpper(status.Status))
			} else {
				outputStatus += fmt.Sprintf("\033[31m%s\033[37m", strings.ToUpper(status.Status))
			}
		}

		if status.Status == "connected" {

			if platform == "windows" {
				outputStatus += fmt.Sprintf(" %s", status.StartFrom)
				outputStatus += fmt.Sprintf(" BPS: %.2f", status.BytesPerSecond)
				outputStatus += fmt.Sprintf(" FPSA: %.2f FPSV: %.2f FPSD: %.2f", status.FramesPerSecond.Audio,
					status.FramesPerSecond.Video, status.FramesPerSecond.Data)
			} else {
				outputStatus += fmt.Sprintf(" \033[33m%s\033[37m", status.StartFrom)
				outputStatus += fmt.Sprintf(" BPS: \033[32m%.2f\033[37m", status.BytesPerSecond)
				outputStatus += fmt.Sprintf(" FPSA: \033[32m%.2f\033[37m FPSV: \033[32m%.2f\033[37m FPSD: \033[32m%.2f\033[37m",
					status.FramesPerSecond.Audio, status.FramesPerSecond.Video, status.FramesPerSecond.Data)
			}
		}

		fmt.Print("\033[2K\r")
		fmt.Printf("%s", outputStatus)

		<-time.After(time.Millisecond * 500)
	}
}