- Pokémon Essentials Version
- Non-applicable
Hi, I recently decided to try sfeMovie to add video playback in PSDK.
Since it's really heavy in term of dependencies (it add 50MB of dlls thus at least 50MB of RAM usage once loaded) I don't include it in PSDK natively. So this topic is here to tell you how to install it or build it :)
2. Extract the file contents in your PSDK project
2. Compile Ruby SFEMovie: https://gitlab.com/NuriYuri/sfemovie (you need rake, it's built the same way as LiteRGSS so you can follow PSDK Wiki telling how to build PSDK under your OS)
3. Move the built file (SFEMovie.so/SFEMovie.bundle) to the root of your project.
4. Add the script (cf, script section) in your project.
Once the file is created, you can paste the following content in it:
Note: I'm using a thread in this script to put the movie update process in another core of the CPU. This helps to save ~1000 Ruby FPS on a Ryzen 5 2600 compared to the single core version.
Here's the parameter lists:
Here's a picture explaining the difference between aliased and not aliased:
Note: If your project uses a shader on the Graphics object, your video will always be aliased.
1. If you're calling the scene from an event, you should call it like this:
2. If you're calling from a GamePlay::Base / GamePlay::BaseCleanUpdate scene, you should call it like this:
3. If you're calling from a non-standard scene, you should call it like this:
Don't forget that you can omit aliased and skip_delay parameter!
Play a movie stored in Movies without aliasing and not letting the player to skip it:
Play a movie stored in Movies without aliasing and letting the player skip after 5 seconds:
Play a movie stored in Movies with aliasing and letting the player skip after 3.5 seconds:
Play a movie stored in Movies with aliasing and not letting the player to skip it:
Since it's really heavy in term of dependencies (it add 50MB of dlls thus at least 50MB of RAM usage once loaded) I don't include it in PSDK natively. So this topic is here to tell you how to install it or build it :)
Windows Installation
1. Download this file: http://www.mediafire.com/file/bs26jpejg1p86sy/extract_in_your_project_(sfemovie).7z/file2. Extract the file contents in your PSDK project
Linux/Mac Installation
1. Compile sfeMovie: http://sfemovie.yalir.org/latest/start.php2. Compile Ruby SFEMovie: https://gitlab.com/NuriYuri/sfemovie (you need rake, it's built the same way as LiteRGSS so you can follow PSDK Wiki telling how to build PSDK under your OS)
3. Move the built file (SFEMovie.so/SFEMovie.bundle) to the root of your project.
4. Add the script (cf, script section) in your project.
The script
To install the script you need to create a file named "00001 Scene_Movie.rb" inside the scripts folder of your project (cf: https://psdk.pokemonworkshop.fr/wiki/en/manage/install-script.html).Once the file is created, you can paste the following content in it:
Code:
module GamePlay
# Scene responsive of playing a movie (video file)
class Movie < BaseCleanUpdate
# Constant telling if the BGM should automatically be stopped
AUTO_STOP_BGM = true
# Constant telling if the map scene should automatically be hidden
AUTO_HIDE_MAP = true
# Create a new Movie scene
# @param filename [String] name of the file to play
# @param aliased [Boolean] if the scene should use a viewport to ensure the video gets played in native resolution
# @param skip_delay [Float] number of seconds the player has to wait before being able to skip the video
def initialize(filename, aliased = false, skip_delay = Float::INFINITY)
super(true)
auto_require_movie_player
@video = SFE::Movie.new
@video.open_from_file(filename)
@skip_delay = skip_delay
@aliased = aliased
@mutex = Mutex.new
end
def update_inputs
return false unless @start_time
dt = Graphics.current_time - @start_time
if dt > @skip_delay && (Input.trigger?(:A) || Input.trigger?(:B) || Mouse.trigger?(:LEFT))
@video.stop
@running = false
end
return false
end
def update_graphics
return start_video unless @start_time
return @running = false unless @video.playing?
@mutex.synchronize { @video.update_bitmap(@sprite.bitmap) }
@video_thread.wakeup if @video_thread.status
end
private
# Redefine main_end to show map again & clean up the space a bit
def main_end
@video_thread.kill
@video_thread = nil
@video = nil
@__last_scene.sprite_set_visible = true if AUTO_HIDE_MAP && @__last_scene.is_a?(Scene_Map)
super
end
# Function that create an aliased viewport
def create_viewport
super
@viewport.blendmode = BlendMode.new
end
# Create all the graphics for the UI
def create_graphics
create_viewport if @aliased
@sprite = Sprite.new(@viewport)
add_disposable @sprite.bitmap = Bitmap.new(*@video.get_size.map(&:to_i))
add_disposable @sprite unless @aliased
width = @aliased ? @viewport.rect.width : Graphics.width
height = @aliased ? @viewport.rect.height : Graphics.height
@sprite.zoom = width / @sprite.width.to_f
@sprite.y = (height - @sprite.height * @sprite.zoom_y).to_i / 2
@__last_scene.sprite_set_visible = false if AUTO_HIDE_MAP && @__last_scene.is_a?(Scene_Map)
end
def auto_require_movie_player
filename = PSDK_RUNNING_UNDER_WINDOWS ? 'lib/SFEMovie' : 'SFEMovie'
filename += PSDK_RUNNING_UNDER_MAC ? '.bundle' : '.so'
require filename
end
def start_video
Audio.bgm_stop if AUTO_STOP_BGM
@video.play
@video.update
@video.update_bitmap(@sprite.bitmap)
@video_thread = Thread.new do
while @video.playing?
@mutex.synchronize { @video.update }
sleep
end
end
@start_time = Time.new
end
end
end
Note: I'm using a thread in this script to put the movie update process in another core of the CPU. This helps to save ~1000 Ruby FPS on a Ryzen 5 2600 compared to the single core version.
How to use
To use this script you need to call the scene GamePlay::Movie with at least 1 parameter.Here's the parameter lists:
- filename : String representing the filename of the movie to play, it may also include the path to the movie from the root of your project.
- aliased : optional parameter telling if the movie should be aliased (in native resolution) or not.
- skip_delay : optional parameter telling when (in seconds) the movie can be skipped by the player.
Here's a picture explaining the difference between aliased and not aliased:
How to call the GamePlay::Movie scene
There's 3 situations. 1. If you're calling the scene from an event, you should call it like this:
Code:
$scene.call_scene(GamePlay::Movie, filename, aliased, skip_delay)
Code:
call_scene(GamePlay::Movie, filename, aliased, skip_delay)
Code:
Graphics.freeze
GamePlay::Movie.new(filename, aliased, skip_delay).main
Graphics.transition #idk if that's necessary
Don't forget that you can omit aliased and skip_delay parameter!
Examples
Play a movie stored in Movies without aliasing and not letting the player to skip it:
Code:
$scene.call_scene(GamePlay::Movie, 'Movies/mymovie.mp4')
Code:
$scene.call_scene(GamePlay::Movie, 'Movies/mymovie.mp4', false, 5.0)
Code:
$scene.call_scene(GamePlay::Movie, 'Movies/mymovie.mp4', true, 3.5)
Code:
$scene.call_scene(GamePlay::Movie, 'Movies/mymovie.mp4', true)
Supported format
This script support a large variety of video format, you can use MP4 or WEBM instead of AVI. You can even use x265 encoded video for better performances :)- Credits
- - SFML developers (originally Laurent Gomila)
- Loïc Siquet contributed to the Windows support of sfeMovie
- Alexandre Janniaux contributed to the Linux support of sfeMovie
- Martin Bohme as author of the FFmpeg tutorial at http://dranger.com/ffmpeg/
- Xorlium and timidouveg who worked on their own video integration packages from which was partly inspired sfeMovie (their wiki pages do no more exist)
- Stephan Vedder, who worked on subtitles support, integrated FFmpeg updates and continues to bring contributions today
- Nuri Yuri writer of the SFEMovie binding to PSDK
Note: The credit list may become outdated, please refer to this page to get the correct list: http://sfemovie.yalir.org/latest/developers.php