FFmpegFrameRecorder保存视频or rtmp发布
来源:互联网 发布:mac应用程序不能打开 编辑:程序博客网 时间:2024/06/03 21:05
记录一下:javacv/samples/WebcamAndMicrophoneCapture.java
import java.nio.ByteOrder; import java.nio.ShortBuffer; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.Mixer; import javax.sound.sampled.TargetDataLine; import org.bytedeco.javacpp.avcodec; import org.bytedeco.javacv.CanvasFrame; import org.bytedeco.javacv.FFmpegFrameRecorder; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.FrameRecorder.Exception; import org.bytedeco.javacv.OpenCVFrameGrabber; public class WebcamAndMicrophoneCapture { final private static int WEBCAM_DEVICE_INDEX=1; final private static int AUDIO_DEVICE_INDEX=4; final private static int FRAME_RATE = 30; final private static int GOP_LENGTH_IN_FRAMES=60; private static long startTime=0; private static long videoTS=0; public static void main(String[] args) throws Exception, org.bytedeco.javacv.FrameGrabber.Exception { int captureWidth = 1280; int captureHeight = 720; // The available FrameGrabber classes include OpenCVFrameGrabber (opencv_videoio), // DC1394FrameGrabber, FlyCaptureFrameGrabber, OpenKinectFrameGrabber, // PS3EyeFrameGrabber, VideoInputFrameGrabber, and FFmpegFrameGrabber. OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(WEBCAM_DEVICE_INDEX); grabber.setImageWidth(captureWidth); grabber.setImageHeight(captureHeight); grabber.start(); // org.bytedeco.javacv.FFmpegFrameRecorder.FFmpegFrameRecorder(String // filename, int imageWidth, int imageHeight, int audioChannels) // For each param, we're passing in... // filename = either a path to a local file we wish to create, or an // RTMP url to an FMS / Wowza server // imageWidth = width we specified for the grabber // imageHeight = height we specified for the grabber // audioChannels = 2, because we like stereo FFmpegFrameRecorder recorder = new FFmpegFrameRecorder( "rtmp://my-streaming-server/app_name_here/instance_name/stream_name", captureWidth, captureHeight, 2); recorder.setInterleaved(true); // decrease "startup" latency in FFMPEG (see: // https://trac.ffmpeg.org/wiki/StreamingGuide) recorder.setVideoOption("tune","zerolatency"); // tradeoff between quality and encode speed // possible values are ultrafast,superfast, veryfast, faster, fast, // medium, slow, slower, veryslow // ultrafast offers us the least amount of compression (lower encoder // CPU) at the cost of a larger stream size // at the other end, veryslow provides the best compression (high // encoder CPU) while lowering the stream size // (see: https://trac.ffmpeg.org/wiki/Encode/H.264) recorder.setVideoOption("preset","ultrafast"); // Constant Rate Factor (see: https://trac.ffmpeg.org/wiki/Encode/H.264) recorder.setVideoOption("crf","28"); // 2000 kb/s, reasonable "sane" area for 720 recorder.setVideoBitrate(2000000); recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); recorder.setFormat("flv"); // FPS (frames per second) recorder.setFrameRate(FRAME_RATE); // Key frame interval, in our case every 2 seconds -> 30 (fps) * 2 = 60 // (gop length) recorder.setGopSize(GOP_LENGTH_IN_FRAMES); // We don't want variable bitrate audio recorder.setAudioOption("crf","0"); // Highest quality recorder.setAudioQuality(0); // 192 Kbps recorder.setAudioBitrate(192000); recorder.setSampleRate(44100); recorder.setAudioChannels(2); recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC); // Jack 'n coke... do it... recorder.start(); // Thread for audio capture, this could be in a nested private class if you prefer... new Thread(new Runnable() { @Override public void run() { // Pick a format... // NOTE: It is better to enumerate the formats that the system supports, // because getLine() can error out with any particular format... // For us: 44.1 sample rate, 16 bits, stereo, signed, little endian AudioFormat audioFormat = new AudioFormat(44100.0F,16,2, true, false); // Get TargetDataLine with that format Mixer.Info[] minfoSet=AudioSystem.getMixerInfo(); Mixer mixer = AudioSystem.getMixer(minfoSet[AUDIO_DEVICE_INDEX]); DataLine.Info dataLineInfo=new DataLine.Info(TargetDataLine.class, audioFormat); try { // Open and start capturing audio // It's possible to have more control over the chosen audio device with this line: // TargetDataLine line = (TargetDataLine)mixer.getLine(dataLineInfo); TargetDataLine line = (TargetDataLine)AudioSystem.getLine(dataLineInfo); line.open(audioFormat); line.start(); int sampleRate = (int) audioFormat.getSampleRate(); int numChannels = audioFormat.getChannels(); // Let's initialize our audio buffer... int audioBufferSize = sampleRate * numChannels; byte[] audioBytes = new byte[audioBufferSize]; // Using a ScheduledThreadPoolExecutor vs a while loop with // a Thread.sleep will allow // us to get around some OS specific timing issues, and keep // to a more precise // clock as the fixed rate accounts for garbage collection // time, etc // a similar approach could be used for the webcam capture // as well, if you wish ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1); exec.scheduleAtFixedRate(newRunnable() { @Override public void run() { try { // Read from the line... non-blocking int nBytesRead = line.read(audioBytes,0, line.available()); // Since we specified 16 bits in the AudioFormat, // we need to convert our read byte[] to short[] // (see source from FFmpegFrameRecorder.recordSamples for AV_SAMPLE_FMT_S16) // Let's initialize our short[] array int nSamplesRead = nBytesRead / 2; short[] samples = new short[nSamplesRead]; // Let's wrap our short[] into a ShortBuffer and // pass it to recordSamples ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(samples); ShortBuffer sBuff = ShortBuffer.wrap(samples,0, nSamplesRead); // recorder is instance of // org.bytedeco.javacv.FFmpegFrameRecorder recorder.recordSamples(sampleRate, numChannels, sBuff); } catch (org.bytedeco.javacv.FrameRecorder.Exception e) { e.printStackTrace(); } } }, 0, (long)1000/ FRAME_RATE, TimeUnit.MILLISECONDS); } catch (LineUnavailableException e1) { e1.printStackTrace(); } } }).start(); // A really nice hardware accelerated component for our preview... CanvasFrame cFrame = new CanvasFrame("Capture Preview",CanvasFrame.getDefaultGamma()/ grabber.getGamma()); Frame capturedFrame = null; // While we are capturing... while ((capturedFrame = grabber.grab()) != null) { if (cFrame.isVisible()) { // Show our frame in the preview cFrame.showImage(capturedFrame); } // Let's define our start time... // This needs to be initialized as close to when we'll use it as // possible, // as the delta from assignment to computed time could be too high if (startTime == 0) startTime = System.currentTimeMillis(); // Create timestamp for this frame videoTS = 1000 * (System.currentTimeMillis()- startTime); // Check for AV drift if (videoTS > recorder.getTimestamp()) { System.out.println( "Lip-flap correction:" + videoTS + " :" + recorder.getTimestamp()+" ->" + (videoTS - recorder.getTimestamp())); // We tell the recorder to write this frame at this timestamp recorder.setTimestamp(videoTS); } // Send the frame to the org.bytedeco.javacv.FFmpegFrameRecorder recorder.record(capturedFrame); } cFrame.dispose(); recorder.stop(); grabber.stop(); } }
0 0
- FFmpegFrameRecorder保存视频or rtmp发布
- FFmpegFrameRecorder
- rtmp+fms rtmp 视频发布环境
- 发布一个软件,轻新视频录播程序,H264/AAC录制视音频,保存FLV,支持RTMP直播
- rtmp sharedObject服务器端保存
- Android 如何使用juv-rtmp-client.jar向Red5服务器发布实时视频数据
- FLV视频发布的两种方式(HTTP协议和RTMP协议)
- FLV视频发布的两种方式(HTTP协议和RTMP协议)(转)
- FLV视频发布的两种方式(HTTP协议和RTMP协议)
- RTMP视频播放器
- IOS-Rtmp视频播放
- RTMP网页视频抓取
- android视频开发之一Android 如何使用juv-rtmp-client.jar向Red5服务器发布实时视频数据
- 一个可以将usb摄像头的视频和麦克风采集的声音以RTMP协议发布到RTMP Server的应用程序
- H264视频通过RTMP直播
- H264视频通过RTMP发送
- H264视频通过RTMP直播 .
- H264视频通过RTMP直播
- 利用卷积神经网络(CNN)构造社区问答系统
- java内存回收
- Eclipse/Myeclipse控制台中文乱码问题
- arduino esp8266 接线和代码、
- 抽象思维实现各种不同的接口调用
- FFmpegFrameRecorder保存视频or rtmp发布
- 浅谈HTTP中GET和POST的区别
- UIApplication代理方法
- Brodatz纹理图像库
- DBUtils 封装
- HTML格式转JSON格式要注意的问题
- Windows 下openssl安装与配置
- 【以太网数据包】OICQ数据包(QQ)
- JAVA -备忘录设计模式