A little history about test case video recording
So is it possible to record video in HTML5 compatible MP4 format ?
Yes it is, using VLCJ library this problem can be solved. VLCJ is open source library which provides java binding for VLC media player(you can find more details here ). As VLC is portable, open source and cross platform library which works on different type of operating systems, this solution can be used across multiple platforms to record screen.
STEP 1:
add all prerequisites:
Create maven project with below dependencies, or just add these jar files in your project manually
- ATU screen recorder
- Monte Screen Recorder
So is it possible to record video in HTML5 compatible MP4 format ?
Yes it is, using VLCJ library this problem can be solved. VLCJ is open source library which provides java binding for VLC media player(you can find more details here ). As VLC is portable, open source and cross platform library which works on different type of operating systems, this solution can be used across multiple platforms to record screen.
STEP 1:
add all prerequisites:
Create maven project with below dependencies, or just add these jar files in your project manually
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <dependency> <groupId>uk.co.caprica</groupId> <artifactId>vlcj</artifactId> <version>3.10.1</version> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>4.2.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.8</version> <scope>test</scope> </dependency> |
STEP 2:
Add VLC native libraries into your projects lib folder. You can find these libraries in VLC installation(C:\Program Files\VideoLAN\VLC\)
- libvlc.dll
- libvlccore.dll
- plugins directory
STEP 3:
add log4j.xml file into /src/main/resources
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="console" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1} %x - %m%n" /> </layout> </appender> <appender name="file" class="org.apache.log4j.RollingFileAppender"> <param name="append" value="false" /> <param name="maxFileSize" value="5MB" /> <param name="maxBackupIndex" value="5" /> <param name="file" value="logs/ScreenRecorder.log" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" /> </layout> </appender> <root> <priority value="info" /> <appender-ref ref="console" /> <appender-ref ref="file" /> </root> </log4j:configuration> |
STEP 4 :
Add code to record screen, (Below sample code uses 64-bit JVM and VLC libraries)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | package com.exprimentalqa.screenrecorder; import java.io.File; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sun.jna.NativeLibrary; import uk.co.caprica.vlcj.player.MediaPlayer; import uk.co.caprica.vlcj.player.MediaPlayerFactory; import uk.co.caprica.vlcj.runtime.RuntimeUtil; public class ScreenRecorder { private final Logger logger = LoggerFactory.getLogger(ScreenRecorder.class); private static final String[] OPTIONS = { "--quiet", "--quiet-synchro", "--intf", "dummy" }; private static final String MRL = "screen://"; private static final String SOUT = ":sout=#transcode{vcodec=h264,vb=%d,scale=%f}:duplicate{dst=file{dst=%s}}"; private static final String FPS = ":screen-fps=%d"; private static final String CACHING = ":screen-caching=%d"; private static final int fps = 20; private static final int caching = 500; private static final int bits = 1024; private static final float scale = 0.5f; private final MediaPlayerFactory mediaPlayerFactory; private final MediaPlayer mediaPlayer; public ScreenRecorder() { NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), System.getProperty("user.dir")+"/lib"); System.setProperty("VLC_PLUGIN_PATH", System.getProperty("user.dir")+"/lib/plugins"); mediaPlayerFactory = new MediaPlayerFactory(OPTIONS); mediaPlayer = mediaPlayerFactory.newHeadlessMediaPlayer(); } public void startRecording(String testName) { String mp4FileName = getFile(testName); logger.info("start recording, "+ mp4FileName); mediaPlayer.playMedia(MRL, getMediaOptions(mp4FileName)); } public void stopRecording() { logger.info("stop recording "); mediaPlayer.stop(); } public void releaseRecordingResources() { mediaPlayer.release(); mediaPlayerFactory.release(); } private String getFile(String testName) { File dir = new File(System.getProperty("user.dir"), "mp4Result"); dir.mkdirs(); DateFormat df = new SimpleDateFormat("yyyyMMdd-HHmmss"); return dir.getAbsolutePath() + "/" + testName + "-" + df.format(new Date()) + ".mp4"; } private String[] getMediaOptions(String destination) { return new String[] { String.format(SOUT, bits, scale, destination), String.format(FPS, fps), String.format(CACHING, caching) }; } } |
STEP 5:
Let's record tests, testNG ITestListner can be implemented to start and stop recording.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package com.exprimentalqa.listeners; import org.testng.ITestContext; import org.testng.ITestListener; import org.testng.ITestResult; import com.exprimentalqa.screenrecorder.ScreenRecorder; public class TestListener implements ITestListener { ScreenRecorder recordTest; public void onFinish(ITestContext arg0) { recordTest.releaseRecordingResources(); } public void onStart(ITestContext arg0) { recordTest = new ScreenRecorder(); } public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) { recordTest.stopRecording(); } public void onTestFailure(ITestResult arg0) { recordTest.stopRecording(); } public void onTestSkipped(ITestResult arg0) { recordTest.stopRecording(); } public void onTestStart(ITestResult arg0) { recordTest.startRecording(arg0.getName()); } public void onTestSuccess(ITestResult arg0) { recordTest.stopRecording(); } } |
STEP 6:
Now test if it is working by creating testNG test method,
1 2 3 4 5 6 | @Test public void test2() { logger.info("start test 2"); // perform selenium test operations logger.info("end of test 2"); } |
By changing trnacoding url you can record video in other HTML5 compatible format i.e. .ogg or .webm Try below mentioned transcode URLs and check if these are working,
1 2 | private static final String RECORDINGFORMAT = ".webm"; private static final String SOUT = ":sout=#transcode{vcodec=VP80,vb=%d,scale=%f}:std{access=file{no-overwrite},mux=webm,dst='%s'}"; |
1 2 | private static final String RECORDINGFORMAT = ".ogg"; private static final String SOUT = ":sout=#transcode{vcodec=theo,vb=%d,scale=%f}:std{access=file{no-overwrite},mux=ogg,dst='%s'}"; |
If you are interested more in video operations, check this VLCJ official wiki page and VLC command line examples
ScreenRecoder test project example can be downloaded from this github link
Hi
ReplyDeleteCan we record audio along with the video in it.Video is working fine.
I have not tried audio recording. need to check.
DeleteHi there, I have a question:
ReplyDeleteIs it possible save the video if the script fails before the screenRecorder.stop(); method?
Thanks in advance.
yes, if test script fails TestListener identifies it. So on failure, skip result we are stopping recording which will create mp4 file. It can be further customized by adding extra parameters in config so that you can record video only for failed scripts.
DeleteHi experimental qa, thank you so much for this amazing tutorial. Where can I find the extra script that only record video for failed scripts?
DeleteDoes it work in windows iam getting Unable to load library 'libvlc': Native library (win32-x86-64/libvlc.dll) not found in resource path
ReplyDeletewhen i execute this, i get video files in mp4result folder as expected. but all files are 158 bytes, not working video files. Any ideas?
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDelete