/**
*
* @author greg (at) myrobotlab.org
*
* This file is part of MyRobotLab (http://myrobotlab.org).
*
* MyRobotLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version (subject to the "Classpath" exception
* as provided in the LICENSE.txt file that accompanied this code).
*
* MyRobotLab is distributed in the hope that it will be useful or fun,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* All libraries in thirdParty bundle are subject to their own license
* requirements - please refer to http://myrobotlab.org/libraries for
* details.
*
* http://docs.opencv.org/modules/imgproc/doc/feature_detection.html
* http://stackoverflow.com/questions/19270458/cvcalcopticalflowpyrlk-not-working-as-expected
*
* Enjoy !
*
* */
package org.myrobotlab.opencv;
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.myrobotlab.logging.LoggerFactory;
import org.myrobotlab.logging.Logging;
import org.slf4j.Logger;
public class OpenCVFilterFFmpeg extends OpenCVFilter {
private static final long serialVersionUID = 1L;
public final static Logger log = LoggerFactory.getLogger(OpenCVFilterFFmpeg.class);
FFmpegFrameRecorder z = null;
FFmpegFrameGrabber x = null;
FFmpegFrameRecorder recorder = null;
boolean recording = true;
int sampleAudioRateInHz = 44100;
int frameRate = 30;
transient OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
public OpenCVFilterFFmpeg() {
super();
}
public OpenCVFilterFFmpeg(String name) {
super(name);
}
@Override
public IplImage display(IplImage frame, OpenCVData data) {
return frame;
}
@Override
public void imageChanged(IplImage image) {
initRecorder(String.format("%s.%d.mp4", name, System.currentTimeMillis()));
}
void initRecorder(String filename) {
try {
log.info(String.format("initRecorder %s", filename));
// filename = "rtp"
// filename = "rtmp://0.0.0.0:1888/video/test.flv";
// filename = "rtmp://live:live@128.122.151.108:1935/live/test.flv";
filename = "rtmp://live:live@54.158.155.69:1935/live/test.flv";
filename = "test2.mp4";
filename = "rtmp://127.0.0.1:1935/test.flv";
filename = "test2.mp4.h264.mp4";
filename = "rtmp://demo.myrobotlab.org:8090/feed1.ffm";
filename = "http://demo.myrobotlab.org:8090/feed1.ffm";
recorder = new FFmpegFrameRecorder(filename, imageSize.width(), imageSize.height(), 0);
// recorder.setFormat("flv");
// recorder.setFormat("mp4");
// recorder.setFormat("3gp"); // h263
// recorder.setFormat("avi");
// recorder.setVideoOption("preset", "ultrafast");
// recorder.setSampleRate(sampleAudioRateInHz);
// recorder.setImageWidth(imageSize.width());
// recorder.setImageHeight(imageSize.height());
// recorder.
// avcodec.AV_CODEC_ID_FLV1;
// recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
// recorder.s
// re-set in the surface changed method as well
// recorder.setFrameRate(frameRate);
// recorder.setVideoBitrate(16384);
// recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
recorder.setFormat("flv");
recorder.setSampleRate(sampleAudioRateInHz);
recorder.setFrameRate(30);
recorder.setVideoBitrate(30 * 640 * 480);
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setVideoOption("preset", "ultrafast");
/*
*
* recorder = new FFmpegFrameRecorder(rtmplink, 320, 568, 2);
* recorder.setInterleaved(true);
* recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
* recorder.setVideoBitrate(videoBitRate);
* recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
* recorder.setFormat("flv"); recorder.setVideoOption("preset",
* "veryfast"); recorder.setVideoOption("tune", "zerolatency");
* recorder.setGopSize(GOP_LENGTH_IN_FRAMES);
* recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
* recorder.setSampleRate(sampleAudioRateInHz);
* recorder.setAudioBitrate(audioBitRate);
* recorder.setFrameRate(frameRate);
*/
recorder.start();
log.info("recorder.setFrameRate(frameRate)");
// Create audio recording thread
// audioRecordRunnable = new AudioRecordRunnable();
// audioThread = new Thread(audioRecordRunnable);
/*
*
* recorder = new FFmpegFrameRecorder(filePath, width, height);
* recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
* recorder.setFormat("mp4"); recorder.setFrameRate(VIDEO_FPS);
* recorder.setVideoBitrate(16384);
* recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
*/
/*
* FrameRecorder recorder = new FFmpegFrameRecorder(
* 'newvideo.mp4",grabber.getImageWidth(),grabber.getImageHeight());
* recorder.setFormat("mp4");
* recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
* recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
* recorder.setFrameRate(5); int height=grabber.getImageHeight(); int
* width=grabber.getImageWidth(); int bitrate=(int) (height*width*5*0.07);
* recorder.setVideoBitrate(bitrate); System.out.println(
* "Grabber videoprocess Bitrate::"+bitrate);
*/
} catch (Exception e) {
Logging.logError(e);
}
}
// Start the capture
public void startRecording() {
try {
if (recorder == null) {
initRecorder(name);
}
recorder.start();
// startTime = System.currentTimeMillis();
recording = true;
// audioThread.start();
} catch (FFmpegFrameRecorder.Exception e) {
e.printStackTrace();
}
}
public void stopRecording() {
// This should stop the audio thread from running
// runAudioThread = false;
if (recorder != null && recording) {
recording = false;
log.info("Finishing recording, calling stop and release on recorder");
try {
recorder.stop();
recorder.release();
} catch (Exception e) {
Logging.logError(e);
}
recorder = null;
}
}
@Override
public IplImage process(IplImage image, OpenCVData data) {
// TODO: support audio?
// boolean runAudioThread = true;
// Set the thread priority
// android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
// Audio
// int bufferSize = 2048;
// short[] audioData;
// int bufferReadResult;
// bufferSize = AudioRecord.getMinBufferSize(sampleAudioRateInHz,
// AudioFormat.CHANNEL_CONFIGURATION_MONO,
// AudioFormat.ENCODING_PCM_16BIT);
// audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
// sampleAudioRateInHz, AudioFormat.CHANNEL_CONFIGURATION_MONO,
// AudioFormat.ENCODING_PCM_16BIT, bufferSize);
// audioData = new short[bufferSize];
log.info("audioRecord.startRecording()");
// audioRecord.startRecording();
// Audio Capture/Encoding Loop
// while (runAudioThread) {
// Read from audioRecord
// bufferReadResult = audioRecord.read(audioData, 0,
// audioData.length);
// if (bufferReadResult > 0) {
// log.info("audioRecord bufferReadResult: " + bufferReadResult);
// Changes in this variable may not be picked up despite it being
// "volatile"
if (recording) {
try {
// recorder.setTimestamp(videoTimestamp);
recorder.record(converter.convert(image));
/*
* Buffer[] buffer = {ShortBuffer.wrap(audioData, 0, bufferReadResult)};
* recorder.record(buffer);
*
* // Write to FFmpegFrameRecorder
* recorder.record(ShortBuffer.wrap(audioData, 0, bufferReadResult));
*/
// recorder.stop();
} catch (FFmpegFrameRecorder.Exception e) {
log.info(e.getMessage());
e.printStackTrace();
}
}
// }
log.info("AudioThread Finished");
/* Capture/Encoding finished, release recorder */
/*
* if (audioRecord != null) { audioRecord.stop(); audioRecord.release();
* audioRecord = null; log.info("audioRecord released"); }
*/
return image;
}
public void release() {
stopRecording();
}
}