nareix / joy4

Golang audio/video library and streaming server
MIT License
2.66k stars 501 forks source link

No RTSP client example file #11

Open legacyshield opened 7 years ago

legacyshield commented 7 years ago

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.

cmdcloud commented 7 years ago

Yes, it would be nice.

drsect0r commented 7 years ago

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

themotu commented 7 years ago

I'd like to see this too

shermaza commented 7 years ago

+1, I'd like to see as well

drsect0r commented 7 years ago

@nareix Ping :)

caioariede commented 7 years ago

Anyone got it working? Any examples?

marv2097 commented 7 years ago

+1 this would be really helpful.

acls commented 7 years ago

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
}
lidedongsn commented 6 years ago
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))
}