iOS video length does not match real time test length

Hi, I run my tests using TestNG, my current goal is to add the video timestamp to the generated report so if a failure occur it will be easier to find the time of the failed test in the video…
I managed to add the relative timestamp(relative to the starting time of the video) to the report using TestNG’s Reporter class and IInvokedMethodListener interface.
The current status is that for android tests it work perfectly but for iOS tests the video is alway shorter/longer than what it takes in real time…
I tried to play with the .fps option and I managed to generate shorter/longer video but I did not manage to make the video-realtime ratio 1:1(so the timestamps will match the video’s)

Does someone know if there is a “correct” fps value so the video length will be as intended?
I tried the standard ones like 24, 30 and others with no success.
I also saw that MJPEG server records in 30 fps and I even tried to change its settings…
It will be great to get some help regarding, thanks :pray: :upside_down_face:

  1. try switch to method → Get high quality with correct frame rate video recording on iOS - #2 by mykola-mokhnach with iOS 17+
  2. with old method try switch VideoQuality which has LOW, MEDIUM, HIGH or PHOTO
  3. with old method try change videoType to codec with constant bitrate (like on Android). Gives larger file as minus
1 Like

updating that using mobile: startXCTestScreenRecording and mobile: stopXCTestScreenRecording worked for me. Thanks!

3 Likes

Pls confirm later how fast device becoming Full and you need delete recorded video files from it.

I run my tests on a simulator so according to the docs the video is being deleted automatically.
If you use this feature on a real device and it takes a lot of storage then I think a possible solution would be to call POST /wda/shutdown for each test when it finishes as suggested here: appium-xcuitest-driver/docs/reference/execute-methods.md at master · appium/appium-xcuitest-driver · GitHub

Updating for future use.
In order to use mobile: startXCTestScreenRecording I needed to upgrade my tests to use iOS 17+ Personally I used 17.2 and 17.4 versions.
After I finished developing this feature and everything was ready for merging, I noticed something weird. My tests became slower. My tests used to take approximately 30 minutes, after upgrading to iOS 17+ the same tests(exactly same repo just the platform version was different) took over 50 minutes…
I tried to track the issue and eventually I understood that the reason is iOS 17.
As well, I saw the following on appium logs(FYI @mykola-mokhnach):


You can see that the execution of a /click took 20 seconds. It happened too many times during the test execution and this is the reason that my tests became slower…

I could not accept this so I had to use the previous version, I used(iOS 15.5) and now I had to find a new way to make my iOS videos in the same length as they take in real life.

My solution: IOSStartScreenRecordingOptions has the ability to pass ffmpeg some filters. After doing my research I encountered the following in ffmpeg docs: setpts I used the following filter(as shown in theirs examples as well):

.withVideoFilters("setpts=(RTCTIME - RTCSTART) / (TB * 1000000)")

Where RTCTIME is the current time in milliseconds of the current frame and RTCSTART is the time in milliseconds of the first frame of the video - the rest is just to fix the ratio to match ffmpeg’s timestamp.

After doing so I managed to solve my issue and the videos were as expected but, I had a new problem. My video files became too big that I got a buffer overflow error. I solved it as well by doing the following:

  1. Instead of recording my whole test in one video, I recorded it in “chunks”, I used ITestListener’s onStart and onFinish methods so for each test I created a separate video.
  2. The above approach did not solve the problem completely so I had to scale down my videos, I used the following method of IOSStartScreenRecordingOptions:
.withVideoScale("320:-2")

It helped to reduce the video file tremendously! (see the docs for more: Scaling)

If it still would not work so I would probably try to stream my videos in real time to an S3 bucket or alternatively try to find a github project(ffmpeg wrapper or other) that allows me to record my own tests.

My current IOSStartScreenRecordingOptions instance looks like so:

BaseStartScreenRecordingOptions<?> recordingOptions = new IOSStartScreenRecordingOptions()
                    .withTimeLimit(Duration.ofMinutes(25))
                    .withFps(10)
                    .withVideoFilters("setpts=(RTCTIME - RTCSTART) / (TB * 1000000)")
                    .withVideoScale("320:-2")
                    .withVideoType("h264");
            ((CanRecordScreen) driver).startRecordingScreen(recordingOptions);

@mykola-mokhnach @Aleksei Thanks for your help!

1 Like

@ido_oserovitz
Have very similar video recording setup:

  • start right after driver start in ‘beforeMethod’ of testNG
  • stop before driver quit in ‘afterMethod’ of testNG
            ((IOSDriver) driver).startRecordingScreen(
                    new IOSStartScreenRecordingOptions()
                            .withFps(24) // a bit higher yours 10
                            .withVideoScale("320:-2")
                            .withVideoType("h264") // mpeg4 / h264
                            .withTimeLimit(Duration.ofMinutes(10)));

No issue for me with iOS 17. Have latest now on phones 17.4.x. I use java-client 9.2.0 and today pushed increase to 9.2.1 (will see tomorrow night runs).

PS As far as with Android we have only constant bitrate that produces large files I compress such files on fly with ffmpeg command that takes less then 1-2 sec to execute.