Thanks for this addon. I've been trying to use this to record video from an USB camera. In a first run, I can generate a .mp4 file successfully, but when I try to record a second time, I get an error similar to this:
The second .mp4 file never wraps up. I suspect the recording pipe is not being closed properly, but I'm not sure why. Any hints on this?
I'm using OF 0.9.3, and Windows 10. Camera is Logitech C920. My .cpp follows below:
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup() {
Globals::config("config.xml");
//Basic configuration:
ofSetWindowPosition(Globals::window.x, Globals::window.y);
ofSetWindowShape(Globals::window.width, Globals::window.height);
ofSetFullscreen(Globals::windowFullscreen);
ofSetFrameRate(30);
vidGrabber.setVerbose(false);
if (Globals::verbose) {
ofSetLogLevel(OF_LOG_VERBOSE);
vidGrabber.setVerbose(true);
}
micSetDeviceError = true;
cameraSetDeviceError = true;
//Setting up camera device and video recording settings:
#ifdef TARGET_WIN32
vidRecorder.setFfmpegLocation(Globals::FFMPEGLocation); // custom FFMPEG location
#endif
fileName = "video";
fileExt = ".mp4"; // ffmpeg uses the extension to determine the container type. run 'ffmpeg -formats' to see supported formats
vidRecorder.setVideoCodec("mpeg4");
vidRecorder.setVideoBitrate("4000k");
//vidRecorder.setMovFileExtension("mov");
//vidRecorder.setAudioCodec("mp3");
//vidRecorder.setAudioBitrate("192k");
vector <ofVideoDevice> videoDevices = vidGrabber.listDevices();
for (int i = 0; i < videoDevices.size(); i++) {
//cout << " ----> [videoDevice at " << i << "]: " << videoDevices.at(i).deviceName << " -- " << Globals::cameraDeviceName << endl;
if (videoDevices.at(i).deviceName == Globals::cameraDeviceName) {
if (Globals::verbose) {
cout << " ----> OK! Setting up video device at [" << i << "]: " << videoDevices.at(i).deviceName << endl;
}
vidGrabber.setDeviceID(i);
vidGrabber.setDesiredFrameRate(30);
vidGrabber.initGrabber(Globals::video.width, Globals::video.height);
cameraSetDeviceError = false;
}
}
//Setting up microphone device and sound recording settings:
sampleRate = 44100;
channels = 2;
for (int i = 0; i < soundStream.getDeviceList().size(); i++) {
//cout << " ----> [Sound device at " << i << "]: " << soundStream.getDeviceList().at(i).name << " -- " << Globals::micDeviceName << endl;
if (soundStream.getDeviceList().at(i).name == Globals::micDeviceName) {
if (Globals::verbose) {
cout << " ----> OK! Setting up sound device at [" << i << "]: " << soundStream.getDeviceList().at(i).name << endl;
}
soundStream.setDeviceID(i);
soundStream.setup(this, 0, channels, sampleRate, 256, 4);
micSetDeviceError = false;
}
}
isRecording = false;
showRecordingText = false;
canMoveVideoFile = false;
buttonLock = Globals::buttonLock;
ofBackground(0);
ofTrueTypeFont::setGlobalDpi(72);
msgFont.load("Fonts/verdana.ttf", 30, true, true);
msgFont.setLineHeight(20.0f);
msgFont.setLetterSpacing(1.035);
camNotFoundMsg = "Camera nao encontrada.";
audioDevNotFoundMsg = "Dispositivo de gravacao de audio nao encontrado.";
}
void ofApp::exit() {
vidRecorder.close();
}
//--------------------------------------------------------------
void ofApp::update(){
if (!cameraSetDeviceError) {
vidGrabber.update();
if (vidGrabber.isFrameNew() && isRecording) {
bool success = vidRecorder.addFrame(vidGrabber.getPixelsRef());
if (!success) {
ofLogWarning("This frame was not added!");
}
}
}
if (canMoveVideoFile && !vidRecorder.isRecording()) {
moveVideoFile();
canMoveVideoFile = false;
}
}
//--------------------------------------------------------------
void ofApp::draw(){
if (!cameraSetDeviceError && !micSetDeviceError) {
ofSetColor(255, 255, 255);
vidGrabber.draw(0, 0);
if (isRecording) {
ofSetColor(255, 0, 0);
ofCircle(50, Globals::window.height - 50, 20);
if (ofGetFrameNum() % 29 == 0) {
showRecordingText = !showRecordingText;
}
if (showRecordingText) {
ofSetColor(255, 127);
msgFont.drawString("Gravando", 75, Globals::window.height - 40);
}
}
}
else {
ofSetColor(255, 255, 255);
if (cameraSetDeviceError) {
msgFont.drawString(camNotFoundMsg,
Globals::window.width/2 - msgFont.getStringBoundingBox(camNotFoundMsg, 0, 0).width/2,
Globals::window.height / 2 - 100);
}
if (micSetDeviceError){
msgFont.drawString(audioDevNotFoundMsg,
Globals::window.width / 2 - msgFont.getStringBoundingBox(audioDevNotFoundMsg, 0, 0).width / 2,
Globals::window.height / 2 + 100);
}
}
}
//--------------------------------------------------------------
void ofApp::audioIn(float *input, int bufferSize, int nChannels){
if(isRecording)
vidRecorder.addAudioSamples(input, bufferSize, nChannels);
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key){
if (!cameraSetDeviceError) {
if (key == 'r') {
isRecording = !isRecording;
if (isRecording && !vidRecorder.isInitialized()) {
videoFileName = fileName + ofGetTimestampString();
vidRecorder.setup(videoFileName, Globals::video.width, Globals::video.height, 30, sampleRate, channels);
// Start recording
vidRecorder.start();
}
else if (!isRecording && vidRecorder.isInitialized()) {
vidRecorder.setPaused(true);
}
else if (isRecording && vidRecorder.isInitialized()) {
vidRecorder.setPaused(false);
}
}
if (key == 'c') {
isRecording = false;
vidRecorder.close();
//canMoveVideoFile = true;
}
}
}
//--------------------------------------------------------------
void ofApp::moveVideoFile() {
ofFilePath p;
string o = p.getAbsolutePath(videoFileName + fileExt);
string n = Globals::networkMediaFolderPath + videoFileName + fileExt;
MoveFileA(o.c_str(), n.c_str());
}