Overview
The media collection provides access to images and videos uploaded via the MX8 Labs Research Platform dashboard. These media items can be used in questions, filtered dynamically, and reported on using their associated metadata.
The media system is designed for:
- Ad or concept testing
- Filtering or tagging by metadata
- Dynamically pulling content into questions
If no media has been uploaded, a dummy set is used with the default columns:
name,description,product,brand,campaign,agency,id
You can create and upload your own metadata columns via the MX8 Labs Research Platform dashboard.
@property media
Accesses the full media collection. Returns a MediaCollection object which can be iterated and queried.
for media in s.media:
s.select_question("What do you think of this image?", options=["Like", "Dislike"], image=media)
get_media_values(column: str)
Returns all values from a specific metadata column in the media collection.
| Parameter | Type | Required | Description |
|---|---|---|---|
column | str | yes | The metadata column to read from each media item |
car_brands = s.get_media_values("brand")
If the column does not exist on your media, this raises an AttributeError. Use the column names shown in the MX8 Labs Research Platform dashboard, or one of the default columns listed above.
get_image(**filters)
Returns the single image matching the provided metadata filters. The filters must identify exactly one image:
- If more than one image matches, the survey stops with a
ValueErrorsuch asThe media collection contains 2 images with the given parameters, expected no more than 1.Add more filters to narrow the result down to one image, or useget_imagesif you intend to work with every match. - If no image matches, the survey stops with a
ValueErrorsuch asCannot find media that meets the condition brand=Ford.Check the value against the column's available values withget_media_values.
ford_image = s.get_image(brand="Ford")
s.select_question("What do you think of this Ford car?",
options=["Like", "Dislike"],
image=ford_image)
get_video(**filters)
Returns the single video matching the provided metadata filters. As with get_image, the filters must identify exactly one video: more than one match stops the survey with The media collection contains 2 videos with the given parameters, expected no more than 1., and no match stops it with Cannot find media that meets the condition .... Use get_videos when you want to work with every match.
ford_video = s.get_video(brand="Ford")
s.play_video(video=ford_video)
get_images(**filters)
Returns a list of every image matching the provided metadata filters. If no image matches, this raises a ValueError (Cannot find media that meets the condition ...) rather than returning an empty list, so a filter that matches nothing will stop the survey rather than silently skipping the loop.
for image in s.get_images(brand="Ford"):
s.select_question("What do you think of this Ford car?",
options=["Like", "Dislike"],
image=image)
get_videos(**filters)
Returns a list of every video matching the provided metadata filters. As with get_images, a filter that matches no videos raises Cannot find media that meets the condition ... rather than returning an empty list.
for video in s.get_videos(brand="Ford"):
s.play_video(video=video)
Ad Exposure Tagging
For campaign effectiveness studies, exposure data (for example, ad server logs) can be pre-loaded into the MX8 Labs Research Platform and matched to respondents using the identifiers supplied with those records. Two functions make that exposure data available in survey code.
tag_exposed_media(source, field_name, exposed_dimension, number_allowed_unknown_values)
Tags items in the media collection as exposed by matching a media metadata field against the current respondent's exposure values. Exposure data must be pre-loaded for the configured source and dimension.
| Parameter | Type | Required | Description |
|---|---|---|---|
source | str | yes | The exposure source configured with the server-side integration, e.g. "campaign-123" |
field_name | str | yes | The media collection field to match against the exposures |
exposed_dimension | str | no | The exposure dimension to match against; defaults to "brand" |
number_allowed_unknown_values | int | no | The number of values outside the allow-list permitted before the lookup is failed |
s.tag_exposed_media(
source="campaign-123",
field_name="brand",
exposed_dimension="brand",
number_allowed_unknown_values=1,
)
for media in s.media:
s.select_question(
"What do you think of this car?",
options=["Like", "Dislike"],
image=media,
tags=s.tag(exposed=media.exposed),
)
Exposed media items receive a frequency tag containing the exposure count and, when recency data is available, a days_since_exposure tag. The older number_allowed_unknown_brands parameter is a deprecated alias for number_allowed_unknown_values — provide only one of the two.
get_exposed_values(source, exposed_dimension, allowed_values, number_allowed_unknown_values)
Returns the current respondent's exposure values for a configured dimension as a list — useful when you want to branch on exposure without tagging media items. Each returned value carries the same frequency tag, plus a days_since_exposure tag when recency data is available.
| Parameter | Type | Required | Description |
|---|---|---|---|
source | str | yes | The exposure source configured with the server-side integration |
exposed_dimension | str | yes | The exposure dimension to return, e.g. "brand" or "product" |
allowed_values | List[str] | no | Optional list of known values to filter the returned exposures by |
number_allowed_unknown_values | int | no | The number of values outside the allow-list permitted before the question is failed; defaults to 0 |
exposed_products = s.get_exposed_values(
source="campaign-123",
exposed_dimension="product",
allowed_values=["SUV", "Sedan", "Coupe"],
)
DRM and Security
When the Security flag is enabled on a survey, every piece of media served through s.media — images and videos alike — is delivered with a full set of content protections. The protections are always on together; they cannot be toggled individually.
| Protection | What it does |
|---|---|
| Anti-tampering video overlay | A transparent overlay sits on top of every video and detects attempts to modify, replace, or scrape the player. Any tampering pauses playback and invalidates the session. |
| Pause-on-background | Playback automatically pauses the moment the tab, window, or app loses focus. Respondents cannot leave a video running in the background while switching to a screen-capture tool. |
| Right-click prevention | The standard context menu is disabled on media elements, so respondents cannot save the underlying asset directly. |
| Keystroke blocking | Common screen-capture and developer-tool keyboard shortcuts are intercepted while media is on screen. |
| DRM | All video is streamed under the platform's DRM system, which prevents screen recording on mobile devices (iOS and Android both render a black frame in any screenshot or screen capture) and blocks unauthorized decryption on desktop. |
Media is DRM-protected, served over short-lived signed URLs, and watermarked for traceability, with common capture shortcuts intercepted in the browser while media is on screen.
Security is the right default for any study involving unreleased ads, confidential concepts, agency creative, or other material under NDA. For low-sensitivity stimuli (for example, publicly available images used purely for recall), Security can be left off to reduce friction for respondents on older browsers.
Notes
- You can chain filters using multiple keyword arguments (e.g.
brand="Ford", campaign="Summer"); an item must match every filter to be returned - Filtering on a metadata column that does not exist — for example, a typo in a keyword argument name — raises an
AttributeErrorrather than returning no matches, so keyword argument names must match your media's metadata columns exactly - These tools allow dynamic, personalized question flows based on metadata
- Media metadata is automatically included in reporting for grouped analysis
- All media must be uploaded via the MX8 Labs Research Platform dashboard and tied to the current survey project
- See Secure Video Player for the video-specific instrument that pairs with these protections

