Comments (9)
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
}
from joy4.
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))
}
from joy4.
Yes, it would be nice.
from joy4.
Would also greatly appreciate this. Other packages that I found are outdated. Ping @nareix
from joy4.
I'd like to see this too
from joy4.
+1, I'd like to see as well
from joy4.
@nareix Ping :)
from joy4.
Anyone got it working? Any examples?
from joy4.
+1 this would be really helpful.
from joy4.
Related Issues (20)
- How to get FPS?
- How to transcode to VP9 on the fly?
- How to produce fragmented mp4 files? HOT 5
- How to send error to client? HOT 3
- How to use authentication?
- read/write > 4GB size fail
- Extract frame and save to image file
- It doesn't support publish mp3 now
- fatal error: libavresample/avresample.h: No such file or directory HOT 1
- How do I save RTPS streams as MP4 video files?
- could not determine kind of name for C.avcodec_encode_audio2
- Any plans moving forward? HOT 1
- fatal error: libavformat/avformat.h: No such file or directory HOT 2
- FFMPEG RTMP Stream Loop Option? HOT 1
- Invalid memory address or nil pointer dereference in Transcoding example code
- why user authentication set to nil?
- Can you support H265 codec? HOT 1
- rtmp_publish example does not working
- Exception Handling About RTMP server HOT 1
- User disconnection handler HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from joy4.