SofdecTutorials

Sofdec Seamless Playback

In our latest post about Sofdec, we learned how you can render movies – even with an alpha channel – on any object meshes. Another great feature for games is the seamless concatenation of videos during playback. For instance, in interactive storytelling, you could switch to different videos based on the choices of the player.  Since this only involves streaming pre-rendered images, it can be achieved quickly while keeping a low CPU load.

The picture below shows how video branching, for example when the user presses the A or B buttons – is an efficient and simple way to make the narrative evolve in different directions.

CRI Sofdec offers convenient functions for the seamless concatenation of videos. The Unity scene below is from our official SDK.
SDK\unity\samples\UnityProject\Assets\Scenes\crimana\basic\Scene_06_SeamlessSequencePlayback.unity

Let’s take a look at this example. 

For this scene, seven video files were first prepared (shown below). Each time the player presses a button from 1 to 7, the corresponding video is added to the playlist. The videos continue to be seamlessly concatenated and played (in the order of the buttons pressed) until the end of the playlist is reached.


 

This demo relies on the following script:

SDK\unity\samples\UnityProject\Assets\Scenes\crimana\basic\Scene_06_SeamlessSequencePlayback.cs

The code listed below displays the 7 buttons in the top left corner of the screen.

The SetFile function provided by the movie controller object of CRI Sofdec is used to add videos to a playlist. The first video is added by passing the SetMode.New flag, and the subsequent videos are added by passing SetMode.Append. Once the playback is initiated, the videos in the playlist will automatically start playing seamlessly one after the other.


GUILayout.BeginHorizontal(); {
  GUI.enabled = (player_status != Player.Status.PlayEnd);
  for (int i = 0; i < contentsList.Length; i++) {
    string button_string = (i == currentIdx) ? ("<" + (i + 1).ToString() + ">") : (i + 1).ToString();
    if (Scene_00_GUI.Button(button_string, GUILayout.MinHeight(40), GUILayout.MinWidth(40))) {

      if (entryList.Count == 0) {
        movieController.player.SetFile(null, contentsList[i], Player.SetMode.New);
        currentIdx = i;
        entryList.Add(i);
      } else {
        /* If the number of entries in the plug-in is insufficient, it returns false. */
        bool set_result = movieController.player.SetFile(null, contentsList[i], Player.SetMode.Append);
        if (set_result) {
          entryList.Add(i);
        } else {
          Debug.Log("failed SetEntry (entry pool is empty).");
        }
      }

    }
  }
  GUI.enabled = true;
}
GUILayout.EndHorizontal();

As you can see from the code above, it is also possible to trigger events – when the playback of a specific video starts or ends – by checking the value of the player status enumeration Player.Status (in this example, Player.Status.PlayEnd was checked).