Open legacyshield opened 7 years ago
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))
}
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.