{"id":5783,"date":"2025-01-09T15:24:17","date_gmt":"2025-01-09T06:24:17","guid":{"rendered":"https:\/\/blog.criware.com\/?p=5783"},"modified":"2025-08-06T17:34:12","modified_gmt":"2025-08-06T08:34:12","slug":"sofdec-seamless-playback","status":"publish","type":"post","link":"https:\/\/blog.criware.com\/index.php\/2025\/01\/09\/sofdec-seamless-playback\/","title":{"rendered":"Sofdec Seamless Playback"},"content":{"rendered":"<p>In our <a href=\"https:\/\/blog.criware.com\/index.php\/2025\/01\/06\/video-playback-on-meshes-with-sofdec\/\">latest post<\/a> about Sofdec, we learned how you can render movies &#8211; even with an alpha channel &#8211; 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.\u00a0 Since this only involves streaming pre-rendered images, it can be achieved quickly while keeping a low CPU load.<\/p>\n<p>The picture below shows how video branching, for example when the user presses the A or B buttons \u2013 is an efficient and simple way to make the narrative evolve in different directions.<\/p>\n<p style=\"\n    display: block;\n    max-width: 650px;\n    margin: 0 auto;\n\tmargin-bottom:25px;\n\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/seection.png\" alt=\"\" width=\"3521\" height=\"1554\" class=\"alignnone size-full wp-image-5786\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/seection.png 3521w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/seection-300x132.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/seection-1024x452.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/seection-768x339.png 768w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/seection-1536x678.png 1536w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/seection-2048x904.png 2048w\" sizes=\"auto, (max-width: 3521px) 100vw, 3521px\" \/><\/p>\n<p>CRI Sofdec offers convenient functions for the seamless concatenation of videos. The Unity scene below is from our official SDK.<br \/>\n<strong>SDK\\unity\\samples\\UnityProject\\Assets\\Scenes\\crimana\\basic\\Scene_06_SeamlessSequencePlayback.unity<\/strong><\/p>\n<p>Let&#8217;s take a look at this example.&nbsp;<\/p>\n<div style=\"max-width: 700px; margin: 0 auto; margin-bottom:30px;\">\n<div style=\"width: 800px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-5783-1\" width=\"800\" height=\"428\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/seamless-playback-video2.mp4?_=1\" \/><a href=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/seamless-playback-video2.mp4\">https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/seamless-playback-video2.mp4<\/a><\/video><\/div>\n<\/div>\n<p>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.<\/p>\n<p style=\"\n    display: block;\n    max-width: 650px;\n    margin: 0 auto;\n\"><br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/7-videos.png\" alt=\"\" width=\"1374\" height=\"499\" class=\"alignnone size-full wp-image-5784\" srcset=\"https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/7-videos.png 1374w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/7-videos-300x109.png 300w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/7-videos-1024x372.png 1024w, https:\/\/blog.criware.com\/wp-content\/uploads\/2025\/01\/7-videos-768x279.png 768w\" sizes=\"auto, (max-width: 1374px) 100vw, 1374px\" \/>\n<\/p>\n<p>&nbsp;<\/p>\n<p>This demo relies on the following script:<\/p>\n<p><strong>SDK\\unity\\samples\\UnityProject\\Assets\\Scenes\\crimana\\basic\\Scene_06_SeamlessSequencePlayback.cs<\/strong><\/p>\n<p>The code listed below displays the 7 buttons in the top left corner of the screen.<\/p>\n<p style=\"margin-bottom:0px\";>\nThe <strong>SetFile<\/strong> 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 <strong>SetMode.New<\/strong> flag, and the subsequent videos are added by passing <strong>SetMode.Append<\/strong>. Once the playback is initiated, the videos in the playlist will automatically start playing seamlessly one after the other.\n<\/p>\n<pre style=\"width: 94%; margin-bottom: 0px; padding-bottom: 40px;\"><code class=\"hljs php\">\r\nGUILayout.BeginHorizontal(); {\r\n  GUI.enabled = (player_status != Player.Status.PlayEnd);\r\n  for (int i = 0; i < contentsList.Length; i++) {\r\n    string button_string = (i == currentIdx) ? (\"<\" + (i + 1).ToString() + \">\") : (i + 1).ToString();\r\n    if (Scene_00_GUI.Button(button_string, GUILayout.MinHeight(40), GUILayout.MinWidth(40))) {\r\n\r\n      if (entryList.Count == 0) {\r\n        <b style=\"background-color: #bfe0ef;\">movieController.player.SetFile<\/b>(null, contentsList[i], <b style=\"background-color: #bfe0ef;\">Player.SetMode.New<\/b>);\r\n        currentIdx = i;\r\n        entryList.Add(i);\r\n      } else {\r\n        \/* If the number of entries in the plug-in is insufficient, it returns false. *\/\r\n        bool set_result = <b style=\"background-color: #bfe0ef;\">movieController.player.SetFile<\/b>(null, contentsList[i], <b style=\"background-color: #bfe0ef;\">Player.SetMode.Append<\/b>);\r\n        if (set_result) {\r\n          entryList.Add(i);\r\n        } else {\r\n          Debug.Log(\"failed SetEntry (entry pool is empty).\");\r\n        }\r\n      }\r\n\r\n    }\r\n  }\r\n  GUI.enabled = true;\r\n}\r\nGUILayout.EndHorizontal();\r\n\r\n<\/code><\/pre>\n<p>As you can see from the code above, it is also possible to trigger events &#8211; when the playback of a specific video starts or ends &#8211; by checking the value of the player status enumeration <strong>Player.Status<\/strong> (in this example, <strong>Player.Status.PlayEnd<\/strong> was checked).<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In our latest post about Sofdec, we learned how you can render movies &#8211; even with an alpha channel &#8211;<\/p>\n","protected":false},"author":2,"featured_media":5793,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[6,7,23],"tags":[],"class_list":["post-5783","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sofdec","category-tutorials","category-unity"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/5783","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/comments?post=5783"}],"version-history":[{"count":22,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/5783\/revisions"}],"predecessor-version":[{"id":5810,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/posts\/5783\/revisions\/5810"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media\/5793"}],"wp:attachment":[{"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/media?parent=5783"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/categories?post=5783"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.criware.com\/index.php\/wp-json\/wp\/v2\/tags?post=5783"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}