Funkin/source/funkin/graphics/video/FlxVideo.hx

165 lines
3.5 KiB
Haxe
Raw Normal View History

package funkin.graphics.video;
2021-04-17 23:19:33 -04:00
import flixel.util.FlxColor;
import flixel.util.FlxSignal.FlxTypedSignal;
import funkin.audio.FunkinSound;
import openfl.display3D.textures.TextureBase;
2021-04-17 23:19:33 -04:00
import openfl.events.NetStatusEvent;
import openfl.media.SoundTransform;
2021-04-17 23:19:33 -04:00
import openfl.media.Video;
import openfl.net.NetConnection;
import openfl.net.NetStream;
/**
* Plays a video via a NetStream. Only works on HTML5.
* This does NOT replace hxCodec, nor does hxCodec replace this.
* hxCodec only works on desktop and does not work on HTML5!
*/
class FlxVideo extends FunkinSprite
2021-04-17 23:19:33 -04:00
{
var video:Video;
var netStream:NetStream;
var videoPath:String;
/**
* A callback to execute when the video finishes.
*/
public var finishCallback:Void->Void;
2023-06-15 00:30:01 -04:00
public function new(videoPath:String)
{
super();
this.videoPath = videoPath;
makeGraphic(2, 2, FlxColor.TRANSPARENT);
video = new Video();
video.x = 0;
video.y = 0;
video.alpha = 0;
FlxG.game.addChild(video);
var netConnection:NetConnection = new NetConnection();
netConnection.connect(null);
netStream = new NetStream(netConnection);
netStream.client = {onMetaData: onClientMetaData};
netConnection.addEventListener(NetStatusEvent.NET_STATUS, onNetConnectionNetStatus);
2023-06-15 00:30:01 -04:00
netStream.play(videoPath);
}
/**
* Tell the FlxVideo to pause playback.
*/
2024-02-28 03:53:36 -05:00
public function pauseVideo():Void
{
if (netStream != null)
{
netStream.pause();
}
}
/**
* Tell the FlxVideo to resume if it is paused.
*/
2024-02-28 03:53:36 -05:00
public function resumeVideo():Void
{
// Resume playing the video.
if (netStream != null)
{
netStream.resume();
}
}
var videoAvailable:Bool = false;
var frameTimer:Float;
static final FRAME_RATE:Float = 60;
public override function update(elapsed:Float):Void
{
super.update(elapsed);
if (frameTimer >= (1 / FRAME_RATE))
{
frameTimer = 0;
// TODO: We just draw the video buffer to the sprite 60 times a second.
// Can we copy the video buffer instead somehow?
pixels.draw(video);
}
if (videoAvailable) frameTimer += elapsed;
}
/**
* Tell the FlxVideo to seek to the beginning.
*/
2024-02-28 00:19:08 -05:00
public function restartVideo():Void
{
// Seek to the beginning of the video.
if (netStream != null)
{
netStream.seek(0);
}
}
/**
* Tell the FlxVideo to end.
*/
public function finishVideo():Void
{
netStream.dispose();
FlxG.removeChild(video);
if (finishCallback != null) finishCallback();
}
public override function destroy():Void
{
if (netStream != null)
{
netStream.dispose();
if (FlxG.game.contains(video)) FlxG.game.removeChild(video);
}
super.destroy();
}
/**
* Callback executed when the video stream loads.
* @param metaData The metadata of the video
*/
public function onClientMetaData(metaData:Dynamic):Void
{
video.attachNetStream(netStream);
onVideoReady();
}
function onVideoReady():Void
{
video.width = FlxG.width;
video.height = FlxG.height;
videoAvailable = true;
FunkinSound.onVolumeChanged.add(onVolumeChanged);
onVolumeChanged(FlxG.sound.muted ? 0 : FlxG.sound.volume);
makeGraphic(Std.int(video.width), Std.int(video.height), FlxColor.TRANSPARENT);
}
function onVolumeChanged(volume:Float):Void
{
netStream.soundTransform = new SoundTransform(volume);
}
function onNetConnectionNetStatus(event:NetStatusEvent):Void
{
if (event.info.code == 'NetStream.Play.Complete') finishVideo();
}
2021-04-17 23:19:33 -04:00
}