Repository metrics
- Stars
- (6,985 stars)
- PR merge metrics
- (No merged PRs in 30d)
Description
Hi, I'm working on rtmp push program with javacv recently, now, simply create a demo read local file to rtmp, code like below, It works ok. Because I don't have many a/v process knowledge before, I'm worried about some detail(which I don't know about) when the project upto prod env in the future. Please help me about My worries:
-
If the framerate is 30/s, how to control the push speed to rtmp server, now I simply make a sleep, I think it's not a correct method. I want to control speed, because, I don't want to push faster than 30/s( this will cause some problem on rtmp server or player terminal? ), I also don't want to push slower than 30/s( I think this will cause block on player), Is my opinion is correct? If yes, How to control this record speed? If not, please tell me the recommened practice.
-
I notice that the grabber 、recorder 、frame all have timestamp can be get/set, but no time_base/pts fields in ffmepg c api, So, I think I control timestamp only to do all my time relation work is ok? for example: audio/video sync, push speed, ... If the timestamp field is stable? begin with 0 in all audio/video file?
-
In my scenc, I need to play multi video files looply 7*24, If every recorded frame's timestamp should be set correctly, after days, the frame's timestamp should be set to a very large num, Is my opinion correct?
-
In my code, before frame record, I did't call frame's setTimestamp and the video's frame is 0(return from MixFrameDraw func), In this situation, the program works ok, why? Is the recorder set the timestamp auto internal? or the timestamp is not importent?
Thank you for your patience, waiting for your reply.
`
FFmpegLogCallback.set();
frameGrabber = new FFmpegFrameGrabber(srcfile);
frameGrabber.setPixelFormat(avutil.AV_PIX_FMT_RGBA);
Frame captured_frame = null;
try {
frameGrabber.start();
recorder = new FFmpegFrameRecorder(destfile, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
recorder.setInterleaved(true);
recorder.setVideoOption("tune","zerolatency");
recorder.setVideoOption("preset", "ultrafast");
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setFormat("flv");
//recorder.setPixelFormat(avutil.AV_PIX_FMT_RGBA); // this is not supported.
recorder.setFrameRate(frameGrabber.getFrameRate());
recorder.setVideoBitrate(frameGrabber.getVideoBitrate());
recorder.setAudioBitrate(192000);
recorder.setAudioOptions(frameGrabber.getAudioOptions());
recorder.setAudioQuality(0);
recorder.setSampleRate(44100);
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
recorder.start();
frameGrabber.setTimestamp(0);
while (true) {
try {
captured_frame = frameGrabber.grabFrame();
if (captured_frame == null) {
System.out.println("!!! Failed cvQueryFrame");
break;
}
if(captured_frame.type == Frame.Type.VIDEO){
captured_frame = MixFrameDraw(captured_frame);
Thread.sleep(20); // 2
}else{
//System.out.println("audio frame");
}
recorder.record(captured_frame, AV_PIX_FMT_ARGB);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static Frame MixFrameDraw(Frame frame){
BufferedImage imgFrame = frameConverter.getBufferedImage(frame);
BufferedImage res = new BufferedImage(bufferImgBg.getWidth(), bufferImgBg.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics graphics = res.getGraphics();
graphics.drawImage(bufferImgBg, 0, 0, null);
graphics.drawImage(imgFrame, 100, 100, null);
graphics.drawImage(bufferImgFg, 100, 400, null);
graphics.drawImage(bufferImgSku, 100, 1000, null);
return frameConverter.getFrame(res);
}
`