it’s impossible to get the ids quickly, and you can use alt accounts to bulk upload them, Maybe you can try the Open Cloud Assets API to upload decals?
I have searched wide before this, but I see this for the first time. This might actually be the solution. I’m going to try it out. Thanks for telling me. Time to remember my 5th grade Python knowledge
Can confirm that this does work. I couldn’t remember my Python knowledge from 5th grade so I had to remember my Javascript experience. I was able to write a script that will post an image and return you the assetID.
For anyone interested the code is below. I will make a guide on how to use it once I’m done with the “subtitles” feature. I will write a script that will automatically upload all frames from a folder and store their IDs to the table needed for the module to work. If the rate limitation is actually 60 uploads per 60 seconds then that means you will be able to upload you bad apple video in like 30 minutes, fully automatically, compared to the painful day of clicking, switching alt accounts, getting moderated, and copy pasting numbers to a table.
- The code:
- More in depth tutorial:
This module is pretty cool, it’s pretty tedious and all but you can get cool stuff done with it, awesome job! Heres something that we could do with the help of @bloodbonniekingnoob1 and your module
Good job with this!
Important:
- I have made a python script to upload assets. It’s very simple to use and automatically puts everything together as it shoud. This is only a test version that is not guaranteed to work. Currently known issues: when you get your account moderated it will error. The only way to save your IDs is to copy them from the terminal output and paste them somewhere to store for further usage. You won’t be able to know how much exactly you have done, but if you want use a tool to check the amount of lines, that will be the amount of frames, remove the old ones and start uploading again. Beware, it’s easy to get banned. If you ask who exactly will be banned, it will be the user that created the API key, regardless if it’s a group or a user one.
- How to make an API key? Go to your creator dashboard, under the credidentials tab.
Now create a new API key, name it whatever, select API system as “Assets API” and make sure to add both read and write permissions. Add0.0.0.0/0
as the IP address and create your key. Make sure to copy it and to never share it. Now store it somewhere in a safe place. - How to use the python script? First of all, make sure you have Python installed. Open up a terminal and type
python --version
. If it works then you have Python. Make a new .py file, paste the script from below. Open it and paste your API key in the given position (look the comments). Now depending on who owns the API key, a group or a user, enter the group ID or your User ID of your account, make sure to change.Group()
to.User()
and vice versa. After that, use the video method in the links section to extract your frame. You need to put your .py file inside an empty folder, and then make a folder called “files” inside. Don’t put the .py file inside, it must stay outside the files folder. Extract your frames into that files folder. After you are done, open up a terminal, navigate to the directory usingcd
in terminal. - Now you need to install the libraries needed. Type
pip install rblx-open-cloud
. If pip doesn’t work for you find a guide online on how to fix your Python installation. And now simplypython main.py
. - Be patient, your connection might be slow. It takes quite a lot of time to get those images posted. After it’s done, it will stop printing new assetIDs, it will make a text file called
output.txt
. Open that, this is now your frames table ready to be pasted in Roblox Studio. - If you get banned while you are still uploading it will error, in case it was only 1 asset that was banned, copy the IDs from the terminal output and store them for later. Count the lines to know at which frame it stopped and continue later.
- This is not the final script, I just want to share it while I’m at it for people to test and possibly find an improvement that I missed.
The Python script:
import rblxopencloud
import os
creator = rblxopencloud.Group( # Make sure to change this to .User( if you are using a userid, and to .Group( if you are using a group.
UserID/GroupID, api_key="API_KEY"
) # Change this to your API key you created and copied. Make sure not to share it.
assetIDsArray = []
def uploadAsset(currentFile):
with open(currentFile, "rb") as file:
asset = creator.upload_asset(
file, rblxopencloud.AssetType.Decal, "Example Asset", "Decal Description"
) # Feel free to change the name and description, it doesn't matter.
if isinstance(asset, rblxopencloud.Asset):
print(asset.id)
assetIDsArray.append(asset.id)
else:
while True:
status = asset.fetch_status()
if status:
print(status.id)
assetIDsArray.append(status.id)
break
fileDirectory = './files'
for fileName in os.scandir(fileDirectory):
if fileName.is_file():
uploadAsset(fileName.path)
content = "local FrameIDs = {\n"
for i in range(len(assetIDsArray)):
content += " " + str(assetIDsArray[i]) + ",\n"
content += "}"
with open('./output.txt', 'w') as file:
file.write(content)
file.close()
This script uses a third-party Python library called rblx-open-cloud. More information about it here:
Please share feedback from this script if you used it. I’m still not sure if it fully works. I was able to upload the first 300 frames of the bad apple video, but I’m currently experiencing some internet issues and can’t really be for sure if it did work. My frames appear as “ghost frames” and I don’t know what caused it, probably some privacy issue from permissions. If you experience the same bug, please tell me.
Use the script at your own risk. I do not take responsibility on how you use it. Don’t upload too much with it, since it’s not still confirmed that it works due to the “asset privacy” issue I have. First to try upload a few frames and confirm they do work and appear.
I figured out why the images appear gray. I made an ooppise while reading the documentaion of the Open Cloud API and thought that would upload an Image asset, but in reality it’s a decal. A decal and an Image are different. An Image type uses rbxassetid://id
, while a decal can’t use that. You are still able to convert it though! I’m going to stop making new replies until I finish v1.1 with the subtitles and finished python script to upload them + a new guide on how to use it. Thanks for all compliments, @Haxonium your work is pretty cool! Would love to see how your game will look like in the future, seems interesting.
For more information how to convert a decalID to an imageID read here (before I document it in the post):
Also sorry for any grammar mistakes in my replies, I don’t have enough time at the moment. I write most stuff from my phone.
unfortunate that we have to write our own modules and screenshot a bunch of frames because roblox doesn’t want to let us use their already existing video category.
Ok I’m unsure if i misread that but you need to have each frame screenshotted, right? Because uhh Roblox studio bulk import
One thought I have is why you can’t “buffer” the videos, where instead of loading the entire video, instead you load only, say, the first 15 seconds, and then while those 15 seconds play, you load the next 15 seconds, and so on and so forth. I think this would help loading times a ton.
Wow! That’s really cool. I feel this is going to be used alot!
I think you got confused while reading the script. That’s literally what it does. It loads the first 400 frames of the video at once, then it starts playing them and once the frames start to become low, for example there are only 100 more frames loaded, the script will load the next frames 200, because it uses :Destroy()
, the old frames are no longer rendered on the screen, so it doesn’t create more lag. Also I’m sorry for the big delay, I’m currently experiencing issues with my internet provider and there hasn’t been internet for the past few days. I will get the update done once I solve that issue. If you know Python then you won’t have an issue completing the script yourself, the hardest part was to make the new loading function work since you need to do it on the server.
I’m going to provide a small tutorial for this. I’ve got a website for getting the frames and a script that adds them to a dictionary automatically (may work on it more to skip frames that have the same id in case you accidentally inserted 2 of the same frame)
Update: turned the script into a small module. Things you can do: choose the path of the folder/model/container or whatever
Choose if you’d like to use getchildren or getdescendants.
Oh also you have access to the table, just do Module.FrameTable or something like that.
im trying to add more features since there’s barely anything i can add, but I’m thinking of adding an optional boolean that adds the table to an “universal” module that holds all of the dictionaries.
Also it no longer works because I’m the best at coding, especially modules
edit: module is fully done. I will provide a community resource post soon
Here’s my module for making your life a little easier: Asset dictionary
also here’s the website: https://www.onlineconverter.com/
(By the way, my module works on any type of downloadable asset, aka animation, decal, texture, mesh, image label, image button, shirt (not crap keyboard) and pants)
I am glad to hear that you have made this module. I hope more people will find it useful.
News on Update v1.1!
News on Update v1.1!
I’m almost done finishing up some stuff. Expect the update pretty soon (in a few hours or tomorrow).
What changed?
- A full guide with a video on how to use the module and import the frames (with the new Python script).
- Improved loading times and performance on the low end. Automated some calculations so you don’t have to go around the module yourself.
- Added subtitles, which you will be able to code yourself. They depend on their own format, just like real subtitles. You will need to sync them with the music manually; of course, if you don’t like them or don’t need them, you don’t have to use them. Once again, they are customizable; you can pick the container to play them in. More features to the formatting will come soon. I’m planning to add some features like being able to pick the color or even add a gradient. I also might make it word-for-word with animations in the future, but I still don’t know how to realize that, so I don’t guarantee it.
- Many more things are subject to change; if you have suggestions, don’t hesitate to leave a reply.
The update is not out; it will be in a few hours or tomorrow as of writing this.
Oh, I thought it was loading the whole video. When I went to the demo place and opened the Shift+F3 menu, it appears to be trying to pre-load about ~1300 frames, which I assumed was the whole video.
Update v1.1 is out!
Video Player | v1.1
2023-06-23T21:00:00Z
New Features
Embedded a subtitle code reader into the module.
Implemented a solution for uploading a large number of assets. Use the script here.
Changes
Changed the resample mode of each frame to Pixelated (configure it in the module)
also changed the scale type to fit, both of these changes are optional, you can remove them if the scale adds gray lines and cuts on the screen or if the resample mode makes it too pixelated or low quality on your screen
Image.ResampleMode = Enum.ResamplerMode.Pixelated --// Improves quality on larger screen resolutions. (rarely makes it worse looking)
Image.ScaleType = Enum.ScaleType.Fit --// Adds gray lines if the video does't fit t
Imrpoved documentation.
Better performance.
Added a FPS argument to the function to easily change it.
Removed some useless stuff that caused lag and rearranged some parts to improve readability and performance.
Merged the “Usages” and “Showcase” parts together.
I removed most details from the post so it’s easier to read.
The IDs as in a dictionary? I’ve made a module for getting a type of asset’s IDs into a dictionary. It’s hard to explain lol. Asset dictionary
Hey so it’s me again lol, first of all, great job on the update, the video plays way smooth now, but theres now an issue that I don’t know if it has to do with the frame dimesions or something, basically the videos now have some weird gray frames at the edges like if the video gets cropped instead of filling the entire frame like it did in the 1.0 version, something like this:
It doesn’t seem that you had added something like that hence why I’m asking, overall the module improved quite a lot in smoothness, good job!
That is a small change. I forgot to add, thanks for reminding me. Basically, I set the frame’s resample mode to Pixelated so it looks a little better on bigger screens, and I set the mode to Fit, which creates those lines. To fix it, simply change the size of the container to “fit” exactly the resolution of the video or change it to Image.ScaleType = Enum.ScaleType.Stretch
inside local function loadGroup(framesToLoad)
. I will edit the post to add this change in a few minutes. Both of these changes are optional, and you can remove them completely. Roblox, by default, should set it to stretched. Fit actually makes it fit. I don’t really know how to do UI, but all I know is that the size of the container should be as big as the size of your image to avoid any stretch effects or weird stuff on devices with irregular screen sizes.
- New Code:
local function loadGroup(framesToLoad)
for i=1, framesToLoad do
if FrameTable[#Images + 1] == nil then break end
local Image = Instance.new("ImageLabel")
Image.ZIndex = #Images == 0 and Container.ZIndex or 1 - #Images
Image.AnchorPoint = Vector2.new(.5, .5)
Image.Size = Container.Size
Image.Position = Container.Position
Image.Image = FrameTable[#Images + 1]
Image.ResampleMode = Enum.ResamplerMode.Pixelated
Image.ScaleType = Enum.ScaleType.Stretch
Image.Parent = Container
table.insert(Images, Image)
task.wait()
end
end
- Old Code:
local function loadGroup(framesToLoad)
for i=1, framesToLoad do
if FrameTable[#Images + 1] == nil then break end
local Image = Instance.new("ImageLabel")
local result
if #Images == 0 then
result = Container.ZIndex
else
result = 1 - #Images
end
Image.ZIndex = result
--// Before I used an if statement, but I changed it to a ternary statement to remove that useless variable and just make it more readable.
Image.AnchorPoint = Vector2.new(.5, .5)
Image.Size = Container.Size
Image.Position = Container.Position
Image.Image = FrameTable[#Images + 1]
Image.Parent = Container
table.insert(Images, Image)
task.wait()
end
end