In trying to solve the issues at http://wiki.bitplan.com/index.php/OpenCV#OpenCV_VideoWriter I found the following relevant links:
- Writing x264 from OpenCV 3 with FFmpeg on Linux
- https://answers.opencv.org/question/120081/videowriter-recording-mp4-x264-opencv-31/
- opencv VideoWriter under OSX producing no output
- http://www.fourcc.org/codecs.php
- opencv write webcam output to avi file
and then came up with the code below to try out combinations of extensions and FOURCC codes.
The environment is Mac Os 10.13.6 using Java 8 and Macports 2.6.2. with OpenCV 3.4.8 I also tested things on Ubuntu 18.04 LTS Using OpenJDK 1.8.0_232 with libopencv_java343.so
The messages and files show that none of the 21 combinations i tried work.
What could be the problem and solution to get the videorecording working?
The resulting messages are:
recording: 640x480 mov video with MJPG
OpenCV: FFMPEG: tag 0x47504a4d/'MJPG' is not supported with codec id 7 and format 'mov / QuickTime / MOV'
OpenCV: FFMPEG: fallback to use tag 0x6765706a/'jpeg'
recording: 640x480 mov video with X264
OpenCV: FFMPEG: tag 0x34363258/'X264' is not supported with codec id 27 and format 'mov / QuickTime / MOV'
OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'
recording: 640x480 mov video with H264
OpenCV: FFMPEG: tag 0x34363248/'H264' is not supported with codec id 27 and format 'mov / QuickTime / MOV'
OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'
recording: 640x480 mov video with MP4V
OpenCV: FFMPEG: tag 0x5634504d/'MP4V' is not supported with codec id 12 and format 'mov / QuickTime / MOV'
OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'
recording: 640x480 mov video with AVC1
OpenCV: FFMPEG: tag 0x31435641/'AVC1' is not supported with codec id 27 and format 'mov / QuickTime / MOV'
OpenCV: FFMPEG: fallback to use tag 0x31637661/'avc1'
recording: 640x480 mov video with FMP4
OpenCV: FFMPEG: tag 0x34504d46/'FMP4' is not supported with codec id 12 and format 'mov / QuickTime / MOV'
OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'
recording: 640x480 mov video with JPEG
OpenCV: FFMPEG: tag 0x4745504a/'JPEG' is not supported with codec id 7 and format 'mov / QuickTime / MOV'
OpenCV: FFMPEG: fallback to use tag 0x6765706a/'jpeg'
recording: 640x480 avi video with MJPG
recording: 640x480 avi video with X264
recording: 640x480 avi video with H264
recording: 640x480 avi video with MP4V
OpenCV: FFMPEG: tag 0x5634504d/'MP4V' is not supported with codec id 12 and format 'avi / AVI (Audio Video Interleaved)'
OpenCV: FFMPEG: fallback to use tag 0x34504d46/'FMP4'
recording: 640x480 avi video with AVC1
OpenCV: FFMPEG: tag 0x31435641/'AVC1' is not supported with codec id 27 and format 'avi / AVI (Audio Video Interleaved)'
OpenCV: FFMPEG: fallback to use tag 0x34363248/'H264'
recording: 640x480 avi video with FMP4
recording: 640x480 avi video with JPEG
OpenCV: FFMPEG: tag 0x4745504a/'JPEG' is not supported with codec id 7 and format 'avi / AVI (Audio Video Interleaved)'
OpenCV: FFMPEG: fallback to use tag 0x47504a4d/'MJPG'
recording: 640x480 mpg video with MJPG
OpenCV: FFMPEG: tag 0x47504a4d/'MJPG' is not supported with codec id 7 and format 'mpeg / MPEG-1 Systems / MPEG program stream'
recording: 640x480 mpg video with X264
OpenCV: FFMPEG: tag 0x34363258/'X264' is not supported with codec id 27 and format 'mpeg / MPEG-1 Systems / MPEG program stream'
recording: 640x480 mpg video with H264
OpenCV: FFMPEG: tag 0x34363248/'H264' is not supported with codec id 27 and format 'mpeg / MPEG-1 Systems / MPEG program stream'
recording: 640x480 mpg video with MP4V
OpenCV: FFMPEG: tag 0x5634504d/'MP4V' is not supported with codec id 12 and format 'mpeg / MPEG-1 Systems / MPEG program stream'
recording: 640x480 mpg video with AVC1
OpenCV: FFMPEG: tag 0x31435641/'AVC1' is not supported with codec id 27 and format 'mpeg / MPEG-1 Systems / MPEG program stream'
recording: 640x480 mpg video with FMP4
OpenCV: FFMPEG: tag 0x34504d46/'FMP4' is not supported with codec id 12 and format 'mpeg / MPEG-1 Systems / MPEG program stream'
recording: 640x480 mpg video with JPEG
OpenCV: FFMPEG: tag 0x4745504a/'JPEG' is not supported with codec id 7 and format 'mpeg / MPEG-1 Systems / MPEG program stream'
and the files produced are:
-rw-r--r-- 1 wf 5686 9. Jan 10:19 test_AVC1_2020-01-09101907.avi
-rw-r--r-- 1 wf 185 9. Jan 10:19 test_AVC1_2020-01-09101907.mov
-rw-r--r-- 1 wf 0 9. Jan 10:19 test_AVC1_2020-01-09101907.mpg
-rw-r--r-- 1 wf 5686 9. Jan 10:19 test_FMP4_2020-01-09101907.avi
-rw-r--r-- 1 wf 185 9. Jan 10:19 test_FMP4_2020-01-09101907.mov
-rw-r--r-- 1 wf 0 9. Jan 10:19 test_FMP4_2020-01-09101907.mpg
-rw-r--r-- 1 wf 5686 9. Jan 10:19 test_H264_2020-01-09101907.avi
-rw-r--r-- 1 wf 185 9. Jan 10:19 test_H264_2020-01-09101907.mov
-rw-r--r-- 1 wf 0 9. Jan 10:19 test_H264_2020-01-09101907.mpg
-rw-r--r-- 1 wf 5686 9. Jan 10:19 test_JPEG_2020-01-09101907.avi
-rw-r--r-- 1 wf 185 9. Jan 10:19 test_JPEG_2020-01-09101907.mov
-rw-r--r-- 1 wf 0 9. Jan 10:19 test_JPEG_2020-01-09101907.mpg
-rw-r--r-- 1 wf 5686 9. Jan 10:19 test_MJPG_2020-01-09101907.avi
-rw-r--r-- 1 wf 185 9. Jan 10:19 test_MJPG_2020-01-09101907.mov
-rw-r--r-- 1 wf 0 9. Jan 10:19 test_MJPG_2020-01-09101907.mpg
-rw-r--r-- 1 wf 5686 9. Jan 10:19 test_MP4V_2020-01-09101907.avi
-rw-r--r-- 1 wf 185 9. Jan 10:19 test_MP4V_2020-01-09101907.mov
-rw-r--r-- 1 wf 0 9. Jan 10:19 test_MP4V_2020-01-09101907.mpg
-rw-r--r-- 1 wf 5686 9. Jan 10:19 test_X264_2020-01-09101907.avi
-rw-r--r-- 1 wf 185 9. Jan 10:19 test_X264_2020-01-09101907.mov
-rw-r--r-- 1 wf 0 9. Jan 10:19 test_X264_2020-01-09101907.mpg
Junit TestCase
package nl.vaneijndhoven.dukes.imageview;
import static org.junit.Assert.assertTrue;
import java.io.File;
import org.junit.BeforeClass;
import org.junit.Test;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import com.bitplan.opencv.NativeLibrary;
import nl.vaneijndhoven.opencv.video.ImageUtils;
/**
* test the video recording functionality
*
* @author wf
*
*/
public class TestVideoRecorder {
@BeforeClass
public static void setup() throws Exception {
NativeLibrary.load();
}
@Test
public void testVideoRecorder() {
byte[] testImage = DebugImageServer.testImage();
Mat testMat = ImageUtils.imageBytes2Mat(testImage);
boolean isColor = true;
for (String ext : VideoRecorder.exts) {
for (String FOURCC : VideoRecorder.FOURCCs) {
Size frameSize = new Size(testMat.width(), testMat.height());
VideoRecorder recorder = new VideoRecorder("test", isColor);
recorder.ext=ext;
recorder.FOURCC=FOURCC;
String msg = String.format("recording: %dx%d %s video with %s",
testMat.width(), testMat.height(), ext, FOURCC);
System.out.println(msg);
recorder.start(25.0, frameSize);
for (int i = 1; i <= 50; i++) {
recorder.recordMat(testMat);
}
recorder.stop();
File videoFile = new File(recorder.path);
assertTrue(videoFile.exists());
}
}
}
}
VideoRecorder
package nl.vaneijndhoven.dukes.imageview;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.videoio.VideoWriter;
/**
* record videos
* @author wf
*
*/
public class VideoRecorder {
public static transient final String DATE_FORMAT="yyyy-MM-ddHHmmss";
public static transient final DateFormat dateFormat=new SimpleDateFormat(DATE_FORMAT);
String name;
private VideoWriter save;
private Size frameSize;
private double fps;
String path;
boolean started;
boolean isColor;
public static String exts[]= {"mov","avi","mpg"};
String ext="mov";
public static String FOURCCs[]= { "MJPG", "X264", "H264", "MP4V", "AVC1", "FMP4", "JPEG"};
String FOURCC="mp4v";
/**
* construct me
* @param name - the name of the video - a timestamp will be added
* @param isColor - true if the video is a color video
*/
public VideoRecorder(String name, boolean isColor) {
this.name=name;
this.isColor=isColor;
started=false;
}
// https://stackoverflow.com/questions/53158765/record-and-save-video-stream-use-opencv-in-java
public void start(double fps, Size frameSize) {
this.fps=fps;
this.frameSize=frameSize;
int fourcc = VideoWriter.fourcc(FOURCC.charAt(0), FOURCC.charAt(1), FOURCC.charAt(2), FOURCC.charAt(3));
Date now = new Date();
String timestamp=dateFormat.format(now);
path=String.format("/tmp/%s_%s_%s.%s", name,FOURCC,timestamp,ext);
save = new VideoWriter(path,fourcc, this.fps, this.frameSize, isColor);
started=true;
}
/**
* stop the recording
*/
public void stop() {
save.release();
started=false;
}
/**
* record a single frame
* @param mat - open cv frame to be recorded
*/
public void recordMat(Mat mat) {
save.write(mat);
}
}