Note: The video was created using test1, which uses a 1:1 ratio, and later in the video it was changed to resizeAspect.
iOS-AvrateNG an adaptation of AvrateNG system, optimized for iOS and visionOS platforms. Inspired heavily by the original project, it has been tailored to provide an intuitive video rating experience on Apple devices, including immersive capabilities with visionOS. The app is designed to facilitate quick and easy video ratings, with a flexible interface suitable for research, user studies, or casual feedback.
This app is designed to be run locally (not distributed via the App Store). Below are the basic requirements:
- Install the latest version of Xcode (from the Mac App Store or Apple Developer site).
- Ensure your macOS version is compatible with the installed Xcode.
- To run the app locally on your iPhone or iPad, follow Apple’s official guide:
Running Your App in Simulator or on a Device - Ensure your device is connected via USB, trusted, and appears in Xcode's device list.
Note: Settings password is
123
Before starting a session, you need to upload your files in the correct order to ensure everything is properly recognized by the app.
Start by uploading your config file (.json
) file using the designated upload button. This step is required first, as the configuration file tells the app how to interpret paths, templates, and settings.
The app will read this file and initialize the environment accordingly. If the configuration is valid, the next upload will align with the correct file references.
Once the config file is uploaded, proceed to upload the full folder containing your videos, playlist files, and other resources. This ensures that all paths defined in your config file (.json
) are resolved correctly.
Here's how the input folders are organized:
upload/
├── config.json
├── training.list
├── playlist.list
├── gray.mp4
├── information.txt
├── video1.mp4
├── video2.mp4
└── video3.mp4
iOS-AvrateNG allows for exporting all collected data from the internal database into two separate CSV files: one for ratings and one for questionnaire responses.
rating_data.csv
— Contains all video ratings collected during the session.questionnaire_data.csv
— Contains all questionnaire responses, if a questionnaire was used.
You can view example exported files directly in the repository:
doc/rating_data.csv
– Sample output of collected video ratingsdoc/questionnaire_data.csv
– Sample output of questionnaire responses
Note: The
"1:1"
ratio is written as"1-to-1"
in the CSV file to avoid it being interpreted as a time value (e.g.,01:01
) by apps like Excel.
All general settings can be changed in .json
, e.g.
{
"playlist": "playlist.list",
"training": true,
"trainingsplaylist": "training.list",
"rating_template": "acr",
"shuffle": false,
"questionnaire": false,
"gray_video": "gray.mp4",
"question": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
"orientation": "both",
"information": "information.txt",
"resize": "1:1"
}
Note: The
.json
file used in AvrateNG can be reused. Any unused or missing options can be manually adjusted in the app settings or left at their default values.
iOS-AvrateNG uses a native AVPlayer-based video player compatible with both iOS and visionOS. It ensures consistent playback performance across iPhone, iPad, and visionOS environments.
The player supports the following video-only formats:
- H.264 / AVC (
.mp4
,.mov
,.m4v
) – Highly compatible across all iOS devices - HEVC / H.265 – High-efficiency codec supported on newer hardware
Note: Only video is supported; no spatial video, stereo, or 3D formats are currently handled. Audio tracks are allowed but optional.
The video player is fully native and runs in a 2D window environment in visionOS.
Supported in iPhone & iPad:
horizontal
– Locks to landscape mode.vertical
– Locks to portrait mode.both
– Allows auto-rotation based on device orientation.
The player offers three resize modes available across all supported devices (iPhone, iPad, visionOS):
1:1
– Displays the video in its original resolution, with no scaling. Recommended for pixel-accurate studies.resizeAspect
– Scales to fit the container while preserving the aspect ratio. Letterboxing or pillarboxing may occur.resizeFill
– Stretches to fill the container size, ignoring aspect ratio. May cause distortion.
Note: When using visionOS, only
resizeAspect
andresizeFill
are supported as video resizing modes due to player limitations. If1:1
is specified, it will default toresizeAspect
.
These options can be set via the .json
configuration file using the "resize"
parameter.
"resize": "resizeAspect"
The playlist playlist.list
consists just of lines with corresponding video files, e.g.
01.MOV
02.mp4
You can also define a training playlist training.list
.
The playlists to render are defined in the .json
file. Also set training
to true
or false
in there.
You can specify multiple videos in one playlist entry if you separate them by |
.
01.MOV|01.MOV
02.mp4
The gray_video
or spacing video is an optional feature that can be enabled in the .json
configuration file.
This video is used to create temporal separation between video sequences — it plays before and after each main video (or sequence of videos, depending on the playlist).
You can configure this by adding the following key to your .json
:
"gray_video": "gray.mp4"
There are several rating templates implemented, they can be changed in the .json
. Default template is a classic ACR rating scheme, see e.g. the folder views/ratings/
.
Follow this structure to create a working rating template. This template ensures the system can correctly capture and submit user ratings.
yourTemplate.swift
struct yourTemplate: View {
let onSubmit: ([String: Any]) -> Void
@State private var selectedRating1: Int? // Replace with your desired type
@State private var selectedRating2: String? // Replace with your desired type
@State private var selectedRating3: Float? // Replace with your desired type
@State private var showRatingAlert = false
// Add any additional variables here
var body: some View {
// Your custom UI
Button(action: {
if selectedRating == nil {
showRatingAlert = true
} else {
submitForm()
}
}) {
Text("Submit")
.frame(maxWidth: .infinity)
.padding()
.background(Color.green)
.foregroundColor(.white)
.cornerRadius(8)
}
if showRatingAlert {
Text("Please select a rating.")
.padding()
.frame(maxWidth: .infinity)
.background(Color.red.opacity(0.2))
.foregroundColor(.red)
.cornerRadius(8)
}
}
func submitForm() {
guard let rating1 = selectedRating1 else { return }
guard let rating2 = selectedRating2 else { return }
guard let rating3 = selectedRating3 else { return }
let ratingData: [String: Any] = [
"info1" : rating1,
"info2" : rating2,
"info3" : rating3
// Add more fields as needed
]
onSubmit(ratingData)
}
}
To register your new template, add it to the ratingViewBuilders dictionary:
templateCreation.swift
let ratingViewBuilders: [String: (String, Int, Bool, Bool, @escaping ([String:Any]) -> Void) -> AnyView] = [
// Existing templates...
"yourTemplate": { question, stimuliIdx, train, dev, onSubmit in
AnyView(yourTemplate(question: question, stimuliIdx: stimuliIdx, train: train, dev: dev, onSubmit: onSubmit))
}
]
If your template is correctly defined and registered, it will work seamlessly with the config file and system settings. Just make sure you reference your template by its exact string key.
Note: Please avoid using Form or Table components in your template. These components are not compatible with the current layout and will interfere with the ScrollView implementation included in the skeleton code.
- [https://github.com/antonfollinger](Anton Follinger)
GNU General Public License v3. See LICENSE.TXT file in this repository.