Bad Apple in Roblox (HTTP Python Video Player)

about 3 days ago, i had the idea to continue my Bad Apple in Roblox that i abandoned; and after thousands and thousands of google searches; i present to you Bad Apple in Roblox.

(beware the python script relies on your os memory and could potentially crash)

versions
recent

Screen.rbxm (9.5 KB)

initial commit

Screen.rbxm (7.7 KB)

Github Repository

  • mmm
  • why
  • hmmm
  • no

0 voters

9 Likes

If you actually improve the code and optimize it more to get to the full resolution without losing FPS and performance, then your video player will turn out better than mine.

For the people asking for more context:

I’m currently also making a Video Player (artz is my friend actually :skull: ), but it uses a different way to render it. Compared to his, it’s currently better, but if you try it on a mobile device you will suffer pain, but I doubt his method will be performance friendly for any mobile device, videos need lots of computing power, and no phone has enough of that, especially with Roblox’s bad optimized spaghetti. His method is more reliable for performance at the moment, and it’s much easier to import the video, since it uses a string of pixel data, while my player uses decals, which might create problems for people on the low end or slow connection. My player does this:

  1. Let the game load it’s assets
  2. Start loading the video frames
  3. Make 2 groups of 150-200 frames that are being loaded on the screen each next frame having a lower zindex.
  4. Start to play the video after all frames are preloaded
  5. After 100-200 frames that were played run the same function to load the next group of frames and preload them. Repeat this until there are no more frames to load and let the video finish.
  6. Video finishes and plays it’s tweens to make a smoother transtition from the video to the actual game.

Differences between my method and his:

  1. My depends on how much Render FPS you have, the lower = more inaccuracy of the task.wait() function, which results in frames falling behind and unsyncing with the music and frame rate.
  2. I use each frame from a decal, while he uses a string of pixel data encoded into JSON.
  3. He uses a lot of actors for each pixel, while I use a for loop.

Ways I can improve mine to achieve better performance:

  1. Make a calibration sequence, where the code will measure the starting time and the current time, and depending on how much frames have played, if they were less than how much it should have played, it will remove all of those frames that should have played, which creates a glitchy effect in the video playback, but this same effect can be seen on a lot of low end devices trying to play a large video file, for example a movie, when the processor can’t handle up the video speed it starts to throttle and try to catch up with the audio, which in my case is exactly what I’m going to try and do.
  2. Remove ALL unneccesary calculations or functions in the code, with something that has to be super accurate, any calculation done on the CPU will cause innaccuracy to build up.
  3. Tweak the numbers for all the functions, for example, after how many played frames to load new ones, or how much new ones to load.

This is what I have in mind currently, if I’m wrong please correct me and if you have a suggestion to try tell me.
This is the code:

local TrackControl = require(game:GetService("ReplicatedFirst"):WaitForChild("TrackControl"))

local VideoControl = {}

function VideoControl:GenerateFrames(IDTable)
	local Frames = {}
	for _, v in IDTable do
		table.insert(Frames, "rbxassetid://".. v)
	end
	return Frames
end

function VideoControl:PlayVideo(FrameTable,Container)
	local Frames = table.maxn(FrameTable)
	local Images = {}
	local function loadGroup()
		for i=1, 150 do
			if not FrameTable[1] then return end
			local img = Instance.new("ImageLabel")
			img.ZIndex = if Images[1] then Images[table.maxn(Images)].ZIndex-1 else Container.ZIndex-i
			img.AnchorPoint = Vector2.new(.5, .5)
			img.Size = Container.Size
			img.Position = Container.Position
			img.Image = FrameTable[1]
			img.Visible = true
			img.Parent = Container
			table.insert(Images, img)
			table.remove(FrameTable, 1)
		end
		game:GetService("ContentProvider"):PreloadAsync(Images)
	end
	loadGroup()
	loadGroup()
	game.Workspace.isVideo.Value = true
	repeat task.wait() until game.Workspace.isLoaded.Value == true
	TrackControl:ChangeToLanguage(30, "Russian")
	TrackControl:ChangeTrack(30)
	local loadItterator = 0
	for _, v in Images do
		task.wait(0.0330578512396694)
		v:Destroy()
		task.spawn(function() loadItterator += 1 if loadItterator >= 125 then loadItterator = 0 loadGroup() end end)
	end
	
	Container.Background.Visible = true
	game:GetService("TweenService"):Create(Container, TweenInfo.new(2, Enum.EasingStyle.Exponential, Enum.EasingDirection.InOut), {GroupTransparency = 1}):Play()
	TrackControl:ChangeTrack(math.random(1, 29))
	task.wait(1.5)
	game:GetService("TweenService"):Create(Container.Parent.TrackPlayer, TweenInfo.new(2, Enum.EasingStyle.Exponential, Enum.EasingDirection.InOut), {GroupTransparency = 0}):Play()
	TrackControl:ChangeAutoPlay(true)	
end

return VideoControl

Please ignore any side modules or functions I use and only look at the base code for the video player, for example TrackControl is not a part of the Video Player, but an extra to make the Video Player have slightly better audio playback, but still sound:Play() will do the same as the track module I have, the module just makes it a little simpler and adds smooth tweens (which don’t delay the audio or unsync it with the video)

Edit:
Forgot to add my example, sorry, here it is:

1 Like

i mean in terms of experience with mobile compability, 0; but this thing only works with the localhost unless you host it somewhere (replit, etc) and its not supposed to be in a production environment

I use 1 actor for every row, but i am currently trying to find a more performant and reliable solution

:ok_hand:

1 Like

sorry for the inactivity, something happened to my pc that made my network connection “unidentified”; but its fixed now, i want to inform you with the recent update;

changes:

  • more customization and performance options
  • actually does the job faster and more performant