joy4
joy4 copied to clipboard
No RTSP client example file
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.
Yes, it would be nice.
Would also greatly appreciate this. Other packages that I found are outdated. Ping @nareix
I'd like to see this too
+1, I'd like to see as well
@nareix Ping :)
Anyone got it working? Any examples?
+1 this would be really helpful.
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
}
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))
}