Custom video player taking far too long to load

I’ve been working on a custom video loader in Roblox, and it’s mostly working, but the loading time is painfully slow. :sob:

I’m preloading all the assets successfully, but when it comes to actually displaying the images on screen, it takes several minutes just for a short clip.

Is there a faster or better way to handle this? I’d love to know if there’s something I’m missing or a smarter approach to improve performance. :pray:

local ContentProvider = game:GetService("ContentProvider")
local RunService = game:GetService("RunService")

local Video = {}
Video.__index = Video

function Video.config()
	return {
		FPS = 29.97,
		AspectRatio = 16 / 9,
		Name = "miku_beam",
		TotalFrames = 151,
		Looping = false
	}
end

function Video.new(config)
	local self = setmetatable({}, Video)
	self.config = config or Video.config()
	self.imageTable = {}
	self.imageInstances = {}
	self.frameIndex = 1
	self.playing = false
	self.connection = nil
	self.Loaded = false

	self:_FindFrames()
	self:_CreateImages()

	local success, result = pcall(function()
		self:_Preload()
	end)
	if not success then
		return nil
	end

	self.Loaded = true
	print(self.config.Name .. " video loaded 🥺")
	return self
end

function Video:_FindFrames()
	for i = 1, self.config.TotalFrames do
		table.insert(self.imageTable, "rbxgameasset://Images/" .. self.config.Name .. "_" .. i)
	end
end

function Video:_CreateImages()
	self.folder = Instance.new("Folder")
	self.folder.Name = self.config.Name
	self.folder.Parent = script

	for i, imageUrl in ipairs(self.imageTable) do
		local image = Instance.new("ImageLabel")
		image.Size = UDim2.new(1, 0, 1, 0)
		image.BackgroundTransparency = 1
		image.Image = imageUrl
		image.LayoutOrder = i
		image.ImageTransparency = 1
		image.Visible = true

		image.Parent = self.folder
		self.imageInstances[i] = image
	end
end

function Video:_Preload()
	ContentProvider:PreloadAsync({ self.folder }, function(asset, status)
		print(asset, status)
		if status ~= Enum.AssetFetchStatus.Success and status ~= Enum.AssetFetchStatus.Loading then
			ContentProvider:PreloadAsync({ asset })
		end
	end)
end

function Video:Stop()
	if self.connection then
		self.connection:Disconnect()
		self.connection = nil
	end
	if self.oldFrameInstance then
		self.oldFrameInstance.ImageTransparency = 1
		self.oldFrameInstance = nil
	end
	self.playing = false
	self.frameIndex = 1
end

function Video:Play(frame: Frame)
	self:Stop()
	self.playing = true

	for _, child in frame:GetChildren() do
		if child:IsA("UIAspectRatioConstraint") then
			child:Destroy()
		end
	end
	local UIAspectRatio = Instance.new("UIAspectRatioConstraint")
	UIAspectRatio.AspectRatio = self.config.AspectRatio
	UIAspectRatio.Parent = frame

	for i, image in ipairs(self.imageInstances) do
		image.Parent = frame
		image.ImageTransparency = 0
		repeat task.wait()print(i) until image.isLoaded
		image.ImageTransparency = 1
	end -- this takes like 1 minute to load a 5 second clip ...

	local elapsedTime = 0

	self.connection = RunService.RenderStepped:Connect(function(dt)
		if not self.playing then return end
		elapsedTime += dt
		local frameToShow = math.floor(elapsedTime * self.config.FPS) + 1

		if frameToShow > self.config.TotalFrames then
			if self.config.Looping then
				elapsedTime = 0
				frameToShow = 1
			else
				self:Stop()
				return
			end
		end

		if frameToShow ~= self.frameIndex then
			local current = self.imageInstances[frameToShow]
			if current then
				if self.oldFrameInstance then
					self.oldFrameInstance.ImageTransparency = 1
				end
				current.ImageTransparency = 0
				self.oldFrameInstance = current
				self.frameIndex = frameToShow
			end
		end
	end)
end

return Video

… I figured out a solution :grin:(i probably shouldv thought for a second more before making this post)
I just let them load all at the same time

for i, image in ipairs(self.imageInstances) do
		image.Parent = frame
		image.ImageTransparency = 0
	end
	repeat task.wait() until isAllLoaded(self.imageInstances)
	for i, image in ipairs(self.imageInstances) do
		image.ImageTransparency = 1
	end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.