Table of content

Native iOS SDK – Pre-release

Key features

  • Remote player management
  • iOS 16 support
  • Verified Google IMA support
  • OMSDK support
  • Sample player applications & code samples
  • Fullscreen playback management
  • Fully-featured Player API to access player events, state and native control

Supported versions & requirements

Swift 5+
iOS 13+
Xcode 14+

Getting started

Create an iOS Player Config

As a first step you need to create a custom player configuration for your iOS application in your Dailymotion account. A unique Player Id will be generated which will be required for player initialization in-app, accurate monetization, targeting and attribution.

The custom player configuration can be created and managed either through the “Players” tab in the Partner Space or programmatically via the player REST API.

Note: Please note “Picture-in-Picture”, “First time viewable”, “Aspect ratio” and “Use embedder link when sharing” features won’t be available and are reserved for JavaScript embeds.

Add the SDK to your project

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into Xcode and the Swift compiler.

  1. Click File
  2. Click Add Packages...
  3. Specify the git URL for Dailymotion SDK.

https://github.com/dailymotion/player-sdk-ios

Manual

  1. Clone the Dailymotion SDK git : https://github.com/dailymotion/player-sdk-ios
  2. Copy the Frameworks folder from the cloned git into your project
  3. From Xcode select your project
  4. Select General Tab
  5. Expand Frameworks, Libraries, and Embedded Content section
  6. Open previous copied Frameworks folder
  7. Select Drag and Drop into Frameworks, Libraries, and Embedded section the 3 .xcframework found there.
  8. Build your project

Create and Add a Player view

Import Dailymotion SDK
import DailymotionPlayerSDK
import AVFoundation
import UIKit

class ViewController: UIViewController {
// Container View IBOutlet - host view for the player
  @IBOutlet weak var playerContainerView: UIView!
...
Create the Player view and Add it to view hierarchy
// Please replace the player id with your own Player ID accessed via the Partner HQ or REST API.
    Dailymotion.createPlayer(playerId: "x8w3s", videoId: "x84sh87", playerParameters:  DMPlayerParameters() , playerDelegate: self) { [weak self] playerView, error in
// Wait for Player initialisation and check if self is still allocated
      guard let self = self else {
        return
      }
      // Check For errors
      if let error = error {
        print("Error creating player: \(error)")
      } else {
        guard let playerView = playerView else {
          return
        }
        // Attach the created Player View to your player container View
        let constraints = [
          playerView.topAnchor.constraint(equalTo: self.playerContainerView.topAnchor, constant: 0),
          playerView.bottomAnchor.constraint(equalTo: self.playerContainerView.bottomAnchor, constant: 0),
          playerView.leadingAnchor.constraint(equalTo: self.playerContainerView.leadingAnchor, constant: 0),
          playerView.trailingAnchor.constraint(equalTo: self.playerContainerView.trailingAnchor, constant: 0)
        ]
        // Activate created constraints
        NSLayoutConstraint.activate(constraints)
      }
    }
Implement DMPlayerDelegate :

In order to get the full functionality and full monetisation implementing DMPlayerDelegate is mandatory.

extension ViewController: DMPlayerDelegate {
func player(_ player: DMPlayerView, openUrl url: URL) {
    UIApplication.shared.open(url)
  }
  
  func playerWillPresentFullscreenViewController(_ player: DMPlayerView) -> UIViewController {
    return self
  }
  
  func playerWillPresentAdInParentViewController(_ player: DMPlayerView) -> UIViewController {
    return self
  }
}

Customize the player

The main Player experience is controlled using Player Settings managed in the Partner Space (Players tab) or REST API. Additional runtime customization is achievable using client-side player parameters.

Working with Player Parameters

Additional runtime customization is achievable when embedding the Player using client-side parameters from the table below. These parameters allow you to specify additional Player behavior or pass in required values to a specific Player embed.

NameParameterDefaultDescriptionValuesType
Video IDvideonilThe ID of the video to loadString
Playlist IDplaylistnilThe ID of the playlist to loadString
Advertising ConfigcustomConfignilFor passing in unique keys for advertising purposes. Dictionary [String:String]
Scale mode
scaleModefitTo adjust the player’s video focus"fit""fill""fillLeft""fillRight""fillTop" & "fillBottom"Enum
MutemutefalseTo mute the player"true","false"Boolean
StartstartTime0Specify the time (in seconds) from which the video should start playingNumber
LooploopfalseTo set the video to loop.
Check the dedicated section for more details.
"true","false"Boolean

Example integration

Parameters are passed into the player on player initialization via the createPlayer() method.

var playerParameters = DMPlayerParameters()
playerParameters.loop = true
playerParameters.startTime= 20
playerParameters.mute = true
        
Dailymotion.createPlayer(playerId: "x8w3s", videoId: "x84sh87", playerParameters:  playerParameters) {playerView, error in
  //Handle init
}

Working with the advertising configuration

The advertising parameter is a custom parameter used for targeting and reporting purposes. Verified partners can use the parameter to dynamically pass information to their VAST tag.

Parameters are passed in on player initialization and can be updated dynamically by the Player API.

Some configuration is also required on our side. If more complex use-cases need to be handled we invite you to contact our Ads Ops team. Please see examples of the below embed types on how to pass in the parameter on initialization.

Note, no encoding is required.

Add keys on Player initialization

Advertising values can be passed in via different parameters and keys. It’s possible to send all the values via a single key or add multiple values separately.

  • Working with single/unique keys

Add all key values through a single key, use the customParams key and the customConfig Parameter with the createPlayer() method.

var playerParameters = DMPlayerParameters()
playerParameters.customConfig = ["customParams":"test/value=1234"]
    
Dailymotion.createPlayer(playerId: "x8w3s", videoId: "x84sh87", playerParameters:  playerParameters) {playerView, error in
  //Handle init
}
  • Working with multiple keys

Different pre-defined keys and values can be added and defined separately. Pass the defined keys into the customConfig parameter with the createPlayer() method.

var playerParameters = DMPlayerParameters()
playerParameters.customConfig = ["keysvalues":"category=sports&section=video", "dynamiciu":"12345"]
    
Dailymotion.createPlayer(playerId: "x8w3s", videoId: "x84sh87", playerParameters:  playerParameters) {playerView, error in
  //Handle init
}

Updating the values with the Player API

Use the method setCustomConfig()in order to dynamically update the advertising parameter value, a new value will be sent. This will then get updated when the player loads the next video file.

Dailymotion.createPlayer(playerId: "x8w3s", videoId: "x84sh87", playerParameters:  DMPlayerParameters()) {playerView, error in
    if let playerView = playerView {
      let customConfigDict = ["customParams":"value=1234", "newKey":"newValue"]
      playerView.setCustomConfig(config: customConfigDict)
    }
}

API Reference

Initialization methods

NameInfo Example
Create Player To create the player object DMPlayerView, the object will be returned in the completion closure given as a parameter. Player ID is mandatory and can be created and managed either through the “Players” tab in the Partner Space or programmatically via the player REST API.
Dailymotion.createPlayer(playerId: "PLAYERID", videoId: "VIDEOID", playerParameters: DMPlayerParameters() , playerDelegate: self)

Required configuration methods

After configuring the initialization of the player its required to implement the necessary methods of the protocol DMPlayerDelegate to ensure your application can manage the player in all contexts.

Warning: The below methods need to be configured to ensure your application can manage the player in all contexts

Info Example
Informs the delegate that the app has to open a URL in a browser result as a user action
player(_ player: DMPlayerView, openUrl url: URL
Asks the delegate for a UIViewController to present the player in fullscreen
player​Will​Present​Fullscreen​View​Controller(_:​)
Asks the delegate for a UIViewController to display an Ad dependent by a UIViewController
player​Will​Present​AdInParent​View​Controller(_:​)

Player methods

When the player is loaded you can use the below methods to take full control of the player and interact with it programmatically.

MethodInfoType
load​Content(video​Id:​playlist​Id:​start​Time:​)
To load a video or a playlist. You can play a specific video followed by a playlist by specifying both the video and playlist IDs

Note that the loaded content playback is based on the autostart configuration defined in the PlayerID settings
String?,
String?,
TimeInterval?
play() To play video playback
pause()To pause video playback
setSubtitles(code:)To activate a subtitles track to a specified language if available
String
setQuality(level:)To set the video’s quality to the specified quality
String
seek(to:)To seek to the specified time in video playback in seconds
TimeInterval
setControls(visible:)To enable or disable the player’s controls UI
Bool
setMute(mute:)To set the mute mode of the player
Bool
setCustomConfig(config:)To set the config for ads
Dynamically update the advertising parameter value, use the method to send a new value which then gets updated when the player loads the next video file
Dictionary [String:String]
setScaleMode(config:)To adjust the player view of the video screen
"fit""fill""fillLeft"
"fillRight""fillTop"
 & "fillBottom"
ScaleMode
enum
getState(completion:)To retrieve the current state of the player
StateCompletionHandler
updateParams(params:)To change the following player config values at runtime scaleModemutevolumeenableControls & customConfigDMPlayerParameters

Events

Player events – DMPlayerDelegate

EventINFO
player(_:openUrl:)Informs the delegate that has to open a URL in a browser result as a user action
player(_:didFailWithError:)Sent when the player triggers an error.
player(_:didChangeControls:)Sent when the availability to use our player controls changes
playerDidStart(_:) Sent the first time the player attempts to start the playback, either because of user interaction, an autoplay parameter or an API call (e.g play()loadContent(), etc.)
playerDidEnd(_:) Sent when the playback of the content video, and eventual post-roll ad video is completed
player(_:didChangeVideo:)Sent when a new video has been loaded in the player. (e.g. after calling loadContent({ video: 'xID' }), or at player start-up)
player(_:didChangeVolume:_:)Sent when the volume level or mute state changes
player(_:didReceivePlaybackPermission:)Sent each time any playback request has failed or if the initial playback attempt has succeeded
player(_:didChangePresentationMode:)Sent when the player transitions to or from a Picture-in-Picture state, either native or the Dailymotion version, or when the player enters or exits the fullscreen state
player(_:didChangeScaleMode:)Sent when the scale mode of the player changes after using setScaleMode()
playerDidCriticalPathReady(_:)Sent every time a video is ready to play, or started playing (depending on autoplay settings, and their resolution by the browser), or is unable to play (blocked, restricted, unavailable)

Video events – DMVideoDelegate

EventInfo
video(_:didChangeSubtitles:)Sent when the current subtitle changes
video(_:didReceiveSubtitlesList:) Sent when subtitles are available
video(_:didChangeDuration:)Sent when the duration property of the video becomes available or changes after a new video load
videoDidEnd(_:)Sent when the player completes playback of the content video
videoDidPause(_:)Sent when the video playback has paused
videoDidPlay(_:)Sent when the playback state of the content video is no longer paused, as a result of the play method or the autoplay attribute
videoIsPlaying(_:)Sent when the content video starts playing, after the play or waiting event
video(_:isInProgress:) Sent when the browser is fetching the media data
video(_:didReceiveQualitiesList:)Sent when video qualities are available
video(_:didChangeQuality:)Sent when the video quality changes
video(_:didSeekEnd:)Sent when the player has completed a seeking operation
video(_:didSeekStart:)Sent when the player starts to seek to another position in the video timeline
videoDidStart(_:)Sent when the player begins playback of the content video
video(_:didChangeTime:)Sent when the playback position changes
videoIsBuffering(_:)Sent when the player has to temporarily stop video playback for further buffering of content

Ad events – DMAdDelegate

EventInfo
adDidReceiveCompanions(_:)Sent when a companion ad is received. Companion ads should be played in sync with the main ad (linear/non-linear) by listening to events AD_START and AD_END
ad(_:didChangeDuration:)Sent when the duration property of the video advertisement becomes available or changes after a new video load
ad(_:didEnd:)Sent when the player completes playback of an ad
adDidPause(_:)Sent when the player pauses an ad
adDidPlay(_:)Sent when the ad playback starts or continues after being in a paused state
ad(_:didStart:_:)Sent when the player begins playback of an ad video
ad(_:didChangeTime:)Sent when the playback position of an ad changes
adDidImpression(_:)Sent when the first ad frame is displayed
ad(_:adDidLoaded:)Sent when the player has loaded and buffered the creative’s media and assets either fully or to the extent that it is ready to play the media
adDidClick(_:)Sent when a user clicks on a video ad

Player state

/// The description of the ad
    public var adDescription: String?

    /// If the player does support the native PiP
    public var playerIsPipNativeSupported: Bool?

    /// The advertiser name
    public var adAdvertiserName: String?

    /// The universal ad id node from the VAST or the ad id of the creative node from the VAST
    public var adCreativeAdId: String?

    /// The id of the creative node from the VAST
    public var adCreativeId: String?

    /// The reason why the last ad ended
    public var adEndedReason: String?

    /// Contains the infos about the last error that occurred with the ad
    public var adError: String?

    /// The id of the ad
    public var adId: String?

    /// If an ad resource is running
    public var adIsPlaying: Bool?

    /// If the ad can be skipped by the user at this moment
    public var adIsSkippable: Bool?

    /// The position of the ad in the video
    public var adPosition: String?

    /// The remaining time before the ad can be skipped or -1 if no ad is running
    public var adSkipOffset: Double?

    /// The title of the ad
    public var adTitle: String?

    /// The player current aspect ratio
    public var playerAspectRatio: String?

    /// If the player is ready to play
    public var playerIsCriticalPathReady: Bool?

    /// If the player is allowed to play, depending on the browser permissions
    public var playerIsPlaybackAllowed: Bool?

    /// The reason why the playback has been allowed or not
    public var playerPlaybackPermissionReason: String?

    /// The current mode where the player is displayed
    public var playerPresentationMode: String?

    /// The player’s current scale mode
    public var playerScaleMode: String?

    /// If the video is created for Children
    public var videoIsCreatedForKids: Bool?

    /// If the player controls are enabled
    public var playerAreControlsEnabled: Bool?

    /// If the player is muted
    public var playerIsMuted: Bool?

    /// If the player is currently playing video or ad content
    public var playerIsPlaying: Bool?

    /// If the player is loading the media resource
    public var playerIsBuffering: Bool?

    /// If the next and previous controls in the PiP are enabled
    public var playerIsNavigationEnabled: Bool?

    /// If the player is in replay screen
    public var playerIsReplayScreen: Bool?

    /// If the video required a password to be read
    public var videoIsPasswordRequired: Bool?

    /// If the player is in start screen
    public var playerIsStartScreen: Bool?

    /// If the player has the alert dialog displayed
    public var playerIsAlertDialogDisplayed: Bool?

    /// The id of the video previous video which was played
    public var playerPrevVideo: String?

    /// The id of the video next video in the queue
    public var playerNextVideo: String?

    /// The id of the owner of the video
    public var videoOwnerId: String?

    /// The user name of the owner of the video
    public var videoOwnerUsername: String?

    /// The screen name of the owner of the video
    public var videoOwnerScreenname: String?

    /// The video qualities that are available
    public var videoQualitiesList: [String]?

    /// The quality value of the video loaded
    public var videoQuality: String?

    /// The language codes of the subtitle tracks which are available for the current media resource
    public var videoSubtitlesList: [String]?

    /// The language code of the subtitle track that is currently enabled
    public var videoSubtitles: String?

    /// The unique Id of the video
    public var videoId: String?

    /// The title of the video loaded
    public var videoTitle: String?

    /// The timestamp that corresponds to the creation of the video
    public var videoCreatedTime: Double?

    /// The current volume level. The volume and mute params operate separately, therefore, you could have a player with full volume, but also muted
    public var playerVolume: Double?

    /// The current playback position of an ad in seconds
    public var adTime: Double?

    /// The duration time of the ad resource in seconds
    public var adDuration: Double?

    /// The current playback position of the video in seconds
    public var videoTime: Double?

    /// The duration time of the video resource in seconds
    public var videoDuration: Double?

    public var playerError: DailymotionPlayerSDK.PlayerError?

    public var adCompanion: [DailymotionPlayerSDK.AdCompanion]?

Best practices & code samples

Managing event listeners

For listening to events triggered by the player you must implement the 3 delegate protocols : DMPlayerDelegate , DMVideoDelegate and DMAdDelegate .

Passing the delegate to the player :

In the create player method :

Dailymotion.createPlayer(playerId: "PLAYER_ID",playerDelegate: self, videoDelegate: self, adDelegate: self , completion: { [weak self] (dmPlayer, error) in
      // Create Player Done
})

Or to the created DMPlayerView instance :

Dailymotion.createPlayer(playerId: "PLAYER_ID", completion: { [weak self] (dmPlayer, error) in
      // Create Player Done
      dmPlayer?.playerDelegate = self
      dmPlayer?.videoDelegate = self
      dmPlayer?.adDelegate = self
})

In order to ensure that all events are catch by your delegates we recommend to use the first approach with passing the delegates at the createPlayer method:

Handling fullscreen

The SDK supports built-in Fullscreen feature.

In order for the fullscreen functionality to work, you have to implement DMPlayerDelegate and playerWillPresentFullscreenViewController function where you have to return a view controller that can be presented on :

extension ViewController: DMPlayerDelegate {
func playerWillPresentFullscreenViewController(_ player: DMPlayerView) -> UIViewController {
    return self
  }
}

Checking Fullscreen state :

  1. You can check at any time after player creation if the player is in fullscreen by calling playerView.isFullscreen that will return true if is in fullscreen mode or false if not.
  2. Implementing from DMPlayerDelegate the playerDidPresentationModeChange function, you will get a DMPlayerView.PresentationMode enum that will contain all possible player presentation states : inline , pictureInPicture and fullscreen :
extension ViewController: DMPlayerDelegate {
func playerDidPresentationModeChange(_ player: DMPlayerView, presentationMode: DMPlayerView.PresentationMode) {
switch presentationMode {
    case .fullscreen: break
    case .inline: break
    case .pictureInPicture: break
    default: break
    }
}
}

Sample applications

Sample applications can be found on our GitHub repository: https://github.com/dailymotion/player-sdk-ios-samples

Native & Webview errors

Create Player Closure Error

In order to get a list of possible errors that could occur please follow this link to the Apple Developer documentation

https://developer.apple.com/documentation/foundation/1508628-url_loading_system_error_codes

Error delegate

Error received in the delegate DMPlayerDelegate function didFail are documented and can be found here : Video access error

Reusing & preload the Player

Preload player:
In your application, you can preload the player before the user attempts to play a video. In order to preload the player you have to just create it how is shown in the Create Player View section and store the returned DMPlayerView object.

When ready to show the player, attach the DMPlayerView to the desired view hierarchy and call the load​Content() or play() method depending if you already passed a video id or a playlist id when creating the player.

Reuse player:
When using our player in an application, you can (and should) reuse the same player instance, therefore a single-player instance can load multiple videos by using the load​Content() method.

Changelog

2023-01-10

  • customConfig parameters and setCustomConfig() method now using a Dictionary data type – [String:String]