joy4 icon indicating copy to clipboard operation
joy4 copied to clipboard

No RTSP client example file

Open legacyshield opened this issue 8 years ago • 9 comments

Can you please provide some example file that reads RTSP video and then write the data to some other file?Currently there is no example file relating to RTSP.

legacyshield avatar Sep 13 '16 06:09 legacyshield

Yes, it would be nice.

cmdcloud avatar Nov 09 '16 07:11 cmdcloud

Would also greatly appreciate this. Other packages that I found are outdated. Ping @nareix

drsect0r avatar Dec 16 '16 12:12 drsect0r

I'd like to see this too

themotu avatar Jan 16 '17 18:01 themotu

+1, I'd like to see as well

shermaza avatar Jan 16 '17 18:01 shermaza

@nareix Ping :)

drsect0r avatar Feb 01 '17 19:02 drsect0r

Anyone got it working? Any examples?

caioariede avatar Feb 25 '17 00:02 caioariede

+1 this would be really helpful.

marv2097 avatar Mar 11 '17 16:03 marv2097

I finally got this working. It turned out to be a lot simpler than I thought.

It uses a modified version of CopyFile and CopyPackets from the avutil package in order to stop copying packets from a live stream.

package main

import (
	"flag"
	"io"
	"time"

	"github.com/nareix/joy4/av"
	"github.com/nareix/joy4/av/avutil"
	"github.com/nareix/joy4/format"
)

func init() {
	format.RegisterAll()
}

func main() {
	srcfile := flag.String("src", "rtsp://192.168.1.1/camera1", "Source file")
	dstfile := flag.String("dst", "output.mp4", "Output file")
	max := flag.Int("max", 5, "Max seconds")
	flag.Parse()

	src, err := avutil.Open(*srcfile)
	if err != nil {
		panic(err)
	}
	dst, err := avutil.Create(*dstfile)
	if err != nil {
		panic(err)
	}
	// same as calling avutil.CopyFile(dst, src) but added
	// max duration in case the src is live and never ends
	err = CopyFileMax(dst, src, time.Duration(*max)*time.Second)
	if err != nil {
		panic(err)
	}
}

func CopyPacketsMax(dst av.PacketWriter, src av.PacketReader, max time.Duration) (err error) {
	for {
		var pkt av.Packet
		if pkt, err = src.ReadPacket(); err != nil {
			if err == io.EOF {
				err = nil
				break
			}
			return
		}

		// break when max time has been reached
		if max > 0 && pkt.Time >= max {
			return
		}

		if err = dst.WritePacket(pkt); err != nil {
			return
		}
	}
	return
}

func CopyFileMax(dst av.Muxer, src av.Demuxer, max time.Duration) (err error) {
	var streams []av.CodecData
	if streams, err = src.Streams(); err != nil {
		return
	}
	if err = dst.WriteHeader(streams); err != nil {
		return
	}
	if err = CopyPacketsMax(dst, src, max); err != nil {
		return
	}
	if err = dst.WriteTrailer(); err != nil {
		return
	}
	return
}

acls avatar Mar 20 '17 18:03 acls

package main

import (
	"fmt"
	"github.com/nareix/joy4/av"
	"github.com/nareix/joy4/av/avutil"
	//"github.com/nareix/joy4/av/transcode"
	//"github.com/nareix/joy4/cgo/ffmpeg"
	"github.com/nareix/joy4/format"
	"time"
)
func init() {
	format.RegisterAll()
}

func main() {
	//infile, _ := avutil.Open("http://117.169.120.142:8080/ysten-businessmobile/live/hdzhejiangstv/astv.m3u8")
	infile, _ := avutil.Open("rtmp://live.hkstv.hk.lxdns.com/live/hks")
	//infile, _ := avutil.Open("rtmp://localhost/app/publish")
	//infile, _ := avutil.Open("rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov")
	//infile, _ := avutil.Open("/app/source_file/xiaoxin6.flv")
	streams, _ := infile.Streams()
	/*
		for _, stream := range streams {
			if stream.Type().IsAudio() {
				astream := stream.(av.AudioCodecData)
				fmt.Println(astream.Type(), astream.SampleRate(), astream.SampleFormat(), astream.ChannelLayout())
			} else if stream.Type().IsVideo() {
				vstream := stream.(av.VideoCodecData)
				fmt.Println(vstream.Type(), vstream.Width(), vstream.Height())
			}
		}
	*/
	outfile, _ := avutil.Create("out.mp4")

	fmt.Println("Start recording...")
	var err error
	if err = outfile.WriteHeader(streams); err != nil {
		return
	}

	var start bool = false
	var count int = 0
	var t0 time.Time
	for i := 0; i < 1500; i++ {
		var pkt av.Packet
		if pkt, err = infile.ReadPacket(); err != nil {
			break
		}

		//	fmt.Println("pkt", i, streams[pkt.Idx].Type(), "len", len(pkt.Data), "keyframe", pkt.IsKeyFrame)
		if streams[pkt.Idx].Type() == av.H264 && pkt.IsKeyFrame {
			start = true
			count++
		}

		if start {
			if count == 1 {
				t0 = time.Now()
			}
			outfile.WritePacket(pkt)
		}
	}

	t1 := time.Now()
	if err = outfile.WriteTrailer(); err != nil {
		return
	}

	outfile.Close()
	infile.Close()

	fmt.Printf("Stop recording, took %v to run.\n", t1.Sub(t0))
}

lidedongsn avatar Nov 01 '17 03:11 lidedongsn