#developers
1 messages ยท Page 7 of 1
I'm quite new to developing websites. Became a summer project for me - looking to fetch profile colors for people who login to my site, similar as you have done
you'd have to get the paint ID from their user data, then load the paint from the query in the image above to know how to apply the css
Where are the paint IDs linked to
Like is the paint ID stored through 7TV or is the actual ID what contains the patterns
paint ID is stored in the user data
you would find where "selected": true and "kind": "PAINT"
So through my script, can I use a Web request through something like axios or what
yes
gql requests are always POST, and the query string/variables go in the body ``` fetch('https://7tv.io/v3/gql', {
method: 'POST',
body: JSON.stringify({
query: query UserByConnection...,
variables: { id: "some id" }
})
Where can I find more information to fetch the paints through this method?
if you use postman it has a gql introspection feature that will let you pick and choose the queries with a GUI
im sure theres other better options too
Possible with restapis?
i only meant better options to work with GQL queries
im pretty sure the rest api doesn't return any paint data
Lowkey might have just got chat gpt to do it 

I love AI
const https = require('https');
// Define the username you want to query
const username = 'f1shk1do';
// Fetch the user's active 7TV paint and subscription badge
function fetch7TVUserDetails(username) {
// Define the API endpoint URL
const url = `https://7tv.app/v3/users/${username}`;
// Make the HTTPS GET request
https.get(url, (response) => {
let data = '';
// A chunk of data has been received
response.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received
response.on('end', () => {
try {
// Parse the JSON response
const userData = JSON.parse(data);
// Fetch active paint and subscription badge
const activePaint = userData?.paint || 'No active paint';
const subBadge = userData?.subscriber_badge || 'No subscription badge';
// Log the results
console.log(`User: ${username}`);
console.log(`Active Paint: ${activePaint?.name || activePaint}`);
console.log(`Subscription Badge: ${subBadge?.name || subBadge}`);
} catch (error) {
console.error('Error parsing JSON:', error.message);
}
});
}).on('error', (error) => {
console.error(`Error fetching details for user ${username}:`, error.message);
});
}
// Execute the function
fetch7TVUserDetails(username);
@topaz crown does this look accurate
no lol

I tried ๐ช
https://stepzen.com/docs/using-graphql/making-queries-with-fetch might want to start with the basics of how to make gql requests
:comments:
I'm asking my smart asf dev friend, he does all this sorta stuff. What would I tell him he needs to do. Sorry to ask so much
You've probably already answered my question
jsut tell him look at 7tv's gql schema to find what you need, https://7tv.io/v3/gql is the endpoint
Thanks so much for the help, I'll see what he replies with


Hey,
Is it okay to use the 7tv api for a rich-text editor extension that would allow users embedding the emotes? I'm not sure I understand the TOS correctly, just want to double check 
Also not sure if this is the right place for such question
@topaz crown I've tried to use some AI with your messages, it's gotten somewhere I guess.
fetch('https://7tv.io/v3/gql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
query: `
query UserByConnection($id: String!) {
userByConnection(platform: TWITCH, id: $id) {
cosmetics {
id
selected
kind
}
}
}
`,
variables: { id: "1003921362" } // Ensure this is the correct Twitch user ID
})
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
if (data.errors) {
console.error('GraphQL errors:', data.errors);
return;
}
const cosmetics = data.data.userByConnection.cosmetics;
const selectedPaint = cosmetics.find(cosmetic => cosmetic.selected && cosmetic.kind === "PAINT");
if (!selectedPaint) {
throw new Error('No selected paint found');
}
// Step 2: Fetch the paint details using the paint ID
fetchPaintDetails(selectedPaint.id);
})
.catch(error => console.error('Error fetching user data:', error));
function fetchPaintDetails(paintId) {
fetch('https://7tv.io/v3/gql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
query: `
query GetCosmetic($id: String!) {
cosmetic(id: $id) {
id
name
function
color
image_url
repeat
}
}
`,
variables: { id: paintId.toString() } // Ensure the paintId is passed as a String
})
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
if (data.errors) {
console.error('GraphQL errors:', data.errors);
return;
}
const paint = data.data.cosmetic;
if (!paint) {
throw new Error('No paint details found');
}
applyPaintToPage(paint);
})
.catch(error => console.error('Error fetching paint details:', error));
}
function applyPaintToPage(paint) {
if (paint.image_url) {
document.body.style.backgroundImage = `url(${paint.image_url})`;
document.body.style.backgroundSize = paint.repeat ? 'repeat' : 'cover';
document.body.style.backgroundRepeat = paint.repeat ? 'repeat' : 'no-repeat';
document.body.style.color = '#FFF'; // Adjust text color for readability
} else {
console.log('No background image found.');
}
}
It's getting this error below
AI I love it
Yup, It's so far working with the payload. Just trying to make it display now on a actual page
"data": {
"cosmetics": {
"paints": [
{
"id": "65459be4ed8a01cc905ecaf8",
"kind": "",
"name": "Firebrand",
"function": "RADIAL_GRADIENT",
"color": 0,
"angle": 90,
"stops": [
{
"at": 0.15,
"color": -589569,
"__typename": "CosmeticPaintStop"
},
{
"at": 0.3,
"color": -7012097,
"__typename": "CosmeticPaintStop"
},
{
"at": 1,
"color": -618852353,
"__typename": "CosmeticPaintStop"
}
],
"__typename": "CosmeticPaint"
}
],
"badges": [
{
"id": "62f97e19e46eb00e438a696c",
"kind": "",
"name": "7TV Subscriber - 3 Months",
"tooltip": "7TV Subscriber (3 Months)",
"tag": "sub3",
"__typename": "CosmeticBadge"
}
],
"__typename": "CosmeticsQuery"
}
}
}```
Outputting that which is correct
Just on the actual script now below, can't seem to get it to display on a HTML page
display what
I'm trying to make it display the paint that I currently have on, onto a HTML page. Basically going to add to my website
Will basically have whatever paint I have on, onto this fishkido text.
yea just use the paint cosmetic gradient stops and turn it into the gradient of the texts background
Where do I view/fetch this
Ohh I see
you can take a look at the paint tool in the extension settings and just play around with the options in there. This helps to understand how the paints work
AI I love it
Well when your an idiot like me that's the only option :))
Thanks dude, I'll give it a go
go to https://7tv.app/users/63d688c3a897cb667b7e601b and view network requests
shits broken
self ddos
@south flare
u think that wont exist on redesign?
ah yes, its a feature so we are going to implement it the same way as before
Hey, I used your updated code. It's displaying like this now
Appreciate you helping me 
hopefully looks better at a smaller size
Oh I've seen. It's just not adding the effects or something like that, I think it's a glow or something
That's it in bigger form
ryanpotat is no longer AFK: (no message) (23m, 55s ago)
use that
Can't seem to get it to work... I'm probably doing something horribly wrong.
@topaz crown Sorry to bother again, This picture below is the scripts one.
This is my one
It looks a bit different
Some look normal though
not sure
you could just replicate the extension's code https://github.com/SevenTV/Extension/blob/cc924cbf4483a5436732526418d16002a6e7a6d1/src/composable/useCosmetics.ts#L439
Using this, I've used some of my old code. Still shows the same with the paints. 
isn't it just because of the size
oo sassy
Username change on Twitch doesn't reflect in 7tv until user logs-in on 7tv website (?)
Fun minor bug if true. Affects Chatterino 7.5.1 and ChatIS - namepaint won't show after a Twitch username change until the moment the user logs-in on the 7tv websites. Screenshots show the entitlement.create events in the same session, second is after the user logs-in on the 7tv website (afaik)
I'm too lazy to reproduce, but seems true
is2511, reminder(s) from: neomothdev - make chatis display name paints hehe (10h, 55m ago)
@zinc aspen ๐
Nope, the actual Twitch username I think
You can see the display_name is mostly cut out on the screenshots, but still changes too, yeah. But the main change is the username
my bad forgot it does that already, was chatting on mobile after changing paint and apparently it wont update the paint until i chat on the actual website with 7tv installed
so when i looked at chatis my paint wasnt showing
It only loads the paint after first message and doesn't retroactively apply it to previous messages. Don't think about why too much
correction: only loads paint after first message on a browser with 7tv installed
not after first message in general
That should be false ๐ค
well idk how to explain it then
Sending a message is not enough? That's cringe
chatsen doesn't
you could use zonian's or my bot to update presence if you're on mobile
The problem is not on my end 
how about i just eat your flesh


yummy potato.....
what about after being baked or fried? 
๐ณ
hey ry
@plush kayak nice name
@lone marsh @topaz crown ryan help pls 
i am being asked dev questions and i have no clues
the user query can return the paint id
but there is a seperate query to get the paint information/stops/shadows/image
im not sure the REST api even returns paint id
it doesn't
@rigid narwhal @rugged perch might have found something on broken gifs

post it under there
yes
Ok well
looking up the webp info and comparing it will be useless
Since it's 2 different structures
But comparing the " working " gif and the " broken " gif
Working gif had a ton of info ( since it has been edited with seems like adobe
Old one has less info for sure
But what I want to focus on here is
- Has Color Map
- Transparent Color
- Bits Per Pixel
- Frame Count
Frame count on the old one is 57, new one is 42 ( don't know if that would be an issue anyway )
Color Map on the broken one doesn't exsist, Unlike the Working one
and I don't know why would the Transparent Color be 0 on the broken one, and on the new one is 255 ?
And I don't know if Bits Per Pixel Matter on your uploading structure on 7TV
But so far that's what I got
damn, ok, that's super useful information
It could be the Transparent Color
but don't know if frame count matter, Since you can manually cut frames on the broken one yet it works
Unless I test it out.
I did use Premiere back then to fix the broken gif, but unfortunately don't remember my settings or anything
frame count I also doubt
the also working one I created yesterday through EZ Gif I think has same frame count as the broken one
so what I'm going to try to do is
- Edit the 3 vaues i'm sus about, And see if they can be uploadable after
if it helps here is another working version
I put that one through EZ Gif yesterday and let it optimize it with the lowest possible value
โก๏ธ 
yea, I also tried to change nothing, just upload and download, but that didn't help, it was still not uploadable after that. So I had to adjsut something slightly
it would probably be interesting what the original creator used to create that gif
Maybe they are still on the server, let me check
they are 
as expected, It's the transparent color
huh, interesting
I guess the transparent color must probably be automatically set by the software, because I don't think there is a setting anywhere to set this value
yea sometimes usiong PIL in pythoin gives an error that it has a None Palette, So getting the Palette using PIL again gives a error which means incomplete or corrup[ted gif
I unfortunately have to go to bed since it's already 1am here, but I'd appreciate if you just share any findings you get in here. Tomorrow I can assist with finding the problem again as well
thank you for you help @rugged perch
No problem at all, I found the main issue and now trying alternative fixes to see what could be the actual problem
Goodnight legend 
ftk 
@misty olive 
Yes I can fully confirm it's one of those 3 values:
- Has Color Map
- Transparent Color
- Bits Per Pixel
and MOST LIKELY
- Transparent Color
yea unscreen fixes it by making the frames overlaps ( draws last frame in the next frame )
I think I'm wrong? I uploaded the unscreen version and it worked ( with the overlapping frames ), But checking the meta data, the only value that changed is the Color Resolution Depth
broken was 8 and fixed is 1 which matches with Bits Per Pixel's value
yea I think I'm wrong, it seems like fixed ones have the Bits Per Pixel and Color Resolution Depthand Has Color Map different, the Transparent Color remained the same on some gif's.

So transparent Color changed there, And the Bits Per Pixel changed
So I guess we know where to look now 
For gifs at least but what about avif?
I can try and convert this gif to avif
well converting to AVIF works, And the data it spits is simmilar to mp4 basically
Meaning it's completly different to GIF's meta data ( Which is the where the issue is )
well yes, but avifs haven't been uploading for me
at least ones created with ffmpeg piped into avifenc
@rugged perch
uploading this to 7tv doesn't work
I know that feeling. I tried to change the bit depths 2 days ago and it constantly changed to some completely different value than what I set it to
I'm unfortunately barely worked with avif, so I'm no expert there, but I imagine they probably have similar attributes to gifs?
Definitely gonna try to play around with the gifs after work today
Ok well we at least know the issue in the GIF
I'll test this now
this one is corrupted
the Average Bitrate on that is 0 according to it's meta data
Avg Bitrate : 0 bps
meta data shouldn't prevent it from being converted though, no?
browsers can play it just fine
they can play it
But 7TV uploader has some set of rules I assume
( or whatever package/method you guys use to convert gifs/AVIF's to webp etc... )
yea the bitrate being 0 breaks it in the 7TV Uploader
Converting the AVIF to AVIF using CloudConvert , It works now
Track Duration : 7116799411153 days 9:02:08 
This is your AVIF duration
how come browsers play it just fine?
I don't think browsers care about the meta data
Unlike 7TV's uploader
Maybe there's some specific structure 7TV Uploader follows
I guess it must be something in the image processor of 7TV
yes
it's on github if you want to look
I think this
I might look and see what could prevent such issues and why would it give that error into those 2 specific GIF and AVIF
the same one? ( even though it's an archive ) ?
If neither duration nor timescale are set, avifenc will attempt to use the framerate stored in a y4m header, if present.```
I'm not specifying either to avifenc
it seems to get it from ffmpeg just fine
but maybe that's part of the problem
avif isn't writing metadata for implicit framerates
which could explain the weird duration
and the 0 bitrate as a result

can't access files?
maybe wrong format
yea the documetnation leads to non-exsistant files sorry
Could've moved somewhere else
I don't keep up with this side of things
let me try making a new avif tho
the only reason I'm piping into avifenc to make them is because ffmpeg can't natively make avifs with alpha
(or at least couldn't the last time I checked)
Well 7TV API just returns null
even though it returns the emote ID, but it's not exsistant on the cdn meaning the image processor had an error mid-way
try it out
lemme compare the data and see what's different ( if it works on image processor first )
yea wtf...
So I'm guessing for GIF's they use ffprobe to get the GIF's information
using that manuially on broken/fixed GIF:
Fixed: 228,128,42
Broken: 228,128,57
the last value is the number of packets from that "video" stream or something
nmvm it's the frame count basically 
I still don't know what's the issue inside the image processor of 7TV 
I think at this point we can also inform Troy and Lennart in here about the findings, they should probably have an idea, what the issue inside the image processor could be
ftk chris anson 
@south flare @sudden gust lots of new insights in here regarding problems with the image upload/processing by @rugged perch. Maybe you have an idea what could be going on with the image processor in these cases
this part will be the most important on testing for you guys โซ .
give this man contributor too
you did. Without you we would have probably just accepted at some point that some images/gifs are broken without analyzing further
@sudden gust can u just try whatever image they are failing with on the new image processor and see if this problem is actually something worth investigating
I only do whatever that can help in any chance that involves development/coding or techinical stuff

we chnaged the image processor a lot
Oh you guys have a new one, Makes sesne
we no longer use ffprobe
I can't do it right now, not home
ok well can you try one of the broken gifs on your side and check the new image processing logs of what it gives? Cuz it fails
can u send a broken image again ill try it rn
both fail?
yes
oka
and after exploring, 3 values on the gif itself could interfere with the new image processor
Yes I can fully confirm it's one of those 3 values:
- Has Color Map
- Transparent Color
- Bits Per Pixel
and MOST LIKELY
- Transparent Color
This only applies to GIF's
oh sorry and:
Color Resolution Depth,
processing the gif u supplied works fine
avif failed
{"id":"66c7543b995a0b878d43bd5b","timestamp":"1724339260","fail":{"error":{"message":"encoder: avif: encode color failed","code":"ErrorCodeEncode"}}}
Front-end says " this emote is no longer available "
the current website does not use the new processor
so the AVIF has come ecnoding color error?
AVIF? Lemme check
Image Pixel Depth : 8 8 8
this?
maybe these can help:
Color Primaries : BT.709```
can u show the full stats
yes
thanks
So Color Primaries is correct...
im trying to see if its an issue with libavif or us
it could be libavif though since online websites can process the file and execute it fine...
this is what it made with avif encoding disabled
something is wrong with either libavif encoder or our impl
want me to check the data of each one of these?
nah just check they look fine
and that the timings are correct
{"id":"66c7574435b1cfad7f1a37a4","timestamp":"1724340037","success":{"drive":"seventv-cdn","files":[{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/32x10_static.png"},"contentType":"image/png","width":32,"height":10,"frameCount":1,"size":724,"format":"PngStatic","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/64x20_static.png"},"contentType":"image/png","width":64,"height":20,"frameCount":1,"size":1583,"format":"PngStatic","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/96x30_static.png"},"contentType":"image/png","width":96,"height":30,"frameCount":1,"size":2757,"format":"PngStatic","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/128x40_static.png"},"contentType":"image/png","width":128,"height":40,"frameCount":1,"size":4217,"format":"PngStatic","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/32x10_static.webp"},"contentType":"image/webp","width":32,"height":10,"frameCount":1,"size":138,"format":"WebpStatic","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/64x20_static.webp"},"contentType":"image/webp","width":64,"height":20,"frameCount":1,"size":202,"format":"WebpStatic","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/96x30_static.webp"},"contentType":"image/webp","width":96,"height":30,"frameCount":1,"size":206,"format":"WebpStatic","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/128x40_static.webp"},"contentType":"image/webp","width":128,"height":40,"frameCount":1,"size":262,"format":"WebpStatic","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/32x10.webp"},"contentType":"image/webp","width":32,"height":10,"frameCount":150,"durationMs":4918,"size":21416,"loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/64x20.webp"},"contentType":"image/webp","width":64,"height":20,"frameCount":150,"durationMs":4918,"size":37296,"loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/96x30.webp"},"contentType":"image/webp","width":96,"height":30,"frameCount":150,"durationMs":4918,"size":39674,"loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/128x40.webp"},"contentType":"image/webp","width":128,"height":40,"frameCount":150,"durationMs":4918,"size":47820,"loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/32x10.gif"},"contentType":"image/gif","width":32,"height":10,"frameCount":150,"durationMs":4918,"size":57292,"format":"GifAnim","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/64x20.gif"},"contentType":"image/gif","width":64,"height":20,"frameCount":150,"durationMs":4918,"size":178999,"format":"GifAnim","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/96x30.gif"},"contentType":"image/gif","width":96,"height":30,"frameCount":150,"durationMs":4918,"size":244961,"format":"GifAnim","loopCount":-1},{"path":{"drive":"seventv-cdn","path":"66c7574435b1cfad7f1a37a4/128x40.gif"},"contentType":"image/gif","width":128,"height":40,"frameCount":150,"durationMs":4918,"size":320259,"format":"GifAnim","loopCount":-1}],"inputMetadata":{"path":{"drive":"seventv-cdn-private","path":"66c7574435b1cfad7f1a37a4"},"contentType":"image/avif-sequence","width":768,"height":256,"frameCount":150,"durationMs":5000,"size":22220,"loopCount":-1}}}
was the payload result
Try to local test your AVIF encoder locally
they all work
Although animated webp versions have some weird artifact on the colors
could be heavy comrpession
This one specifically, You can see the compression on that
Nice even discord can't process it? 
yea
No wayyy
its not embedding
it failed to upload
Yea even discord
in brwoser also
interesting

lemme probe that
yep that's what i Mean
we havent tuned it correctly it seems
yea probing it doesn't give any odd values
is this the webp?
discord does not work with animated webp
oh really?
yes
yea you're right
ok well the artifacts on that webP is bad regardless of discord issue
ok so turns out that I actually WAS specifying the fps to avifenc
@rigid narwhal so the issue with pngs was bit depth right? different from gif/avif?
classic webp "compression"
It doesn't like soft moving edges. Hard edges don't have as much of a problem, because it can detect the color change
but yes this is a particularly poignant example of how bad webp can look after going through 7tv
But it shouldn't be this bad though
usually on the current image processor it should be okay
Also why does it fail on the new image processor, that's the real question
ok so
omitting the --fps flag for avifenc makes avifs that DO work
does the image processor still snap the fps to gif timings?
so without passing the --fps flag, What's the default fps
;lemme check that
send me the AVIF that works
after 7tv takes 2 years to process the emote, it ends up being twice as large
which is weird and ick
amazing
this one without the --fps flag correct?
the one with "FPS" in the name is the one that passed the fps flag
maybe if I omitted the fps flag from ffmpeg, and ONLY passed it to avifenc, it would also work
I can try
so this one if broken on 7TV?
no, the one WITH the fps flag is the one that's broken
ok
possibly because it has 2 fps flags
ffmpeg is passing its fps info to avifenc
but ideally the avifenc flag should override it
(expected behavior)
So the MothyFPS one gives this:
Time Scale : 30
Unlike the other oine which gives 25
so 25 fps is the default fps
so ther FPS one is shorter, Yet the media scale is 30
unlike SanityCheck which has 25
and longer by 1 second
the other values are pretty much the same
so it's fps?
checking a few more things
It at least seemed so, yes
which one?
there appear to be multiple by that name
@rugged perch
check this one
Time Scale : 100
100 fps?
idk if that's 100 fps
but timeScale is 100 so i guess it is ? 
oh nevermind the avif did generate, but it just wasn't ready as early as the webp
you wouldn't even need a button
it can be done properly
but mp4 just means h.264 generally, which is less efficient than avif for this application
@rugged perch ok so the "ffmpeg -r only" one was actually still specifying fps to both ffmpeg and avifenc
i dont understand
so could it be the fps?
[image-processor/src/worker/process/encoder/libwebp.rs:57:3] &config = WebPConfig {
lossless: 1,
quality: 100.0,
method: 6,
image_hint: 0,
target_size: 0,
target_PSNR: 0.0,
segments: 4,
sns_strength: 50,
filter_strength: 60,
filter_sharpness: 0,
filter_type: 1,
autofilter: 0,
alpha_compression: 1,
alpha_filtering: 2,
alpha_quality: 100,
pass: 100,
show_compressed: 0,
preprocessing: 1,
partitions: 0,
partition_limit: 0,
emulate_jpeg_size: 0,
thread_level: 1,
low_memory: 0,
near_lossless: 100,
exact: 1,
use_delta_palette: 0,
use_sharp_yuv: 0,
qmin: 0,
qmax: 100,
}
I'm not sure as well
this is the config we use for the webp encoding
because fps isnt a thing
do you detect the fps for the AVIF files? And extract frames?
fps isnt a thing
fps is a way we look at images
but in reality each frame has a duration
Media time then?
its more like a slide show
where each frame is shown for a specific duration
and fps is the average of that
well yea I understand that. But then why does it fail to be processed on your end? no error logs from the libavif at least?
oh you're fixing the compression artifact I'm guessing
yes
lossless = 1?
no shot
lossless webps are massive
and they don't have any visual artifacts
(because they're lossless)
well yea even with loseless = 1 config, It get's artifacts still
that's the issue I think
it's clearly not lossless
:.|:;
my guess would be that the lossless setting is being overridden by all the lossy parameters being specified
i set the thing to lossless to test
new information unveiled!
so specifying the fps/rate to
- avif = extremely long duration with exiftool, and 7tv fails to process, but plays at expected speed in browser
- ffmpeg = defaults to 25 fps
- both = correct frame rate
oh ok nvm
but this is better than the old artifact compression
wayy better
report it to libwebp then 
this is a tiny version though
this is lossless
which is less affected by the artifacts in question
and every single frame is a keyframe
when i do lossless without every frame being a keyframe we get artifacts
this is 100% a libwebp bug
hmm
Mirror only. Please do not send pull requests. See https://chromium.googlesource.com/webm/libwebp/+/HEAD/CONTRIBUTING.md. - webmproject/libwebp
setting this value to 1 solves the issue
which value?
ah
it didn't take me to a line
well yes I would expect that to fix it, but the files will also be much bigger
this is a libwebp issue
I'm not sure about that
it might be something that is tuned poorly, but I think it's functioning as intended
webp is meant for much larger images
emotes are not a good use case for them
and paints with moving soft edges are the worst case
avif handles them like a champ though
our settings are
anim.allowed_mixed = 1;
anim.kmax = 1; // fixes the bug but makes much bigger files.
picture.use_argb = 1;
config.lossless = 1; // doesnt matter;
config.quality = 100; // doesnt seem to matter with the bug;
config.method = 6; // doesnt seem to matter witht he bug.
config.thread_level = 1; // doesnt seem to matter with the bug.
I assume "method" is "compression level"
actually
since they both max out at 6
Mirror only. Please do not send pull requests. See https://chromium.googlesource.com/webm/libwebp/+/HEAD/CONTRIBUTING.md. - webmproject/libwebp
no method is method
explain what these values actually mean
Mirror only. Please do not send pull requests. See https://chromium.googlesource.com/webm/libwebp/+/HEAD/CONTRIBUTING.md. - webmproject/libwebp
setting kmax to like 5 should also reduce the severity of the artifacts without TOO drastically increasing file size
actually
no i mean the values assigned to them
set it to 200 this will totally work !

maybe it's not working like typical keyframes
"contains errors" 
it seems libwebp is making bad images
computer opens it in krita
this is a libwebp bug for sure
library makers
oh 
7WebP
thats unfortunate
chrome plays kmax5 but firefox says it contains errors
yep
if i knew literally fucking anything about manipulating image data i'd try to make one but i dont 
what causes the bug exactly
this image
is this for a paint or
wait really? 
so its not just webp that breaks
strange..
worlds most cursed fucking image ig
Report it to them with the broken samples
In the hope they respond with something
they are fast when its a bug with encoding
because virtually everything depends on this

i'd be SHOCKED if there wasn't a fast response
avif also passes 

perhaps the docker image we have for the image processor is old
they might have already fixed the issue with avif
generate a new one..? 
just to test?
(tbh i have zero fucking clue how docker actually works i need to do research cuz every time i have to use docker i'm basically just winging it)
xd
i know what it is
avif has a width/height multiple requirement
2024-08-22T17:01:16.485615995+00:00 INFO ThreadId(56) ProcessJob::process{job_id=66c76edcfe1bd0ac3bd2f145}: scuffle_image_processor::worker::process: image-processor/src/worker/process/mod.rs:115: starting job
[image-processor/src/worker/process/encoder/libavif.rs:104:4] frame.image.width() = 32
[image-processor/src/worker/process/encoder/libavif.rs:104:4] frame.image.height() = 10
2024-08-22T17:01:16.490963040+00:00 ERROR ThreadId(56) ProcessJob::process{job_id=66c76edcfe1bd0ac3bd2f145}: scuffle_image_processor::worker::process: image-processor/src/worker/process/mod.rs:167: failed to process job: encoder: avif: encode color failed
if i had to guess its multiples of 4
2024-08-22T17:01:16.452807214+00:00 INFO ThreadId(03) process_image:process_image: scuffle_image_processor::management: image-processor/src/management/mod.rs:33: new process image request
2024-08-22T17:01:16.485615995+00:00 INFO ThreadId(56) ProcessJob::process{job_id=66c76edcfe1bd0ac3bd2f145}: scuffle_image_processor::worker::process: image-processor/src/worker/process/mod.rs:115: starting job
[image-processor/src/worker/process/encoder/libavif.rs:104:4] frame.image.width() = 32
[image-processor/src/worker/process/encoder/libavif.rs:104:4] frame.image.height() = 10
2024-08-22T17:01:16.490963040+00:00 ERROR ThreadId(56) ProcessJob::process{job_id=66c76edcfe1bd0ac3bd2f145}: scuffle_image_processor::worker::process: image-processor/src/worker/process/mod.rs:167: failed to process job: encoder: avif: encode color failed
2024-08-22T17:01:45.805677064+00:00 INFO ThreadId(03) process_image:process_image: scuffle_image_processor::management: image-processor/src/management/mod.rs:33: new process image request
2024-08-22T17:01:46.561961161+00:00 INFO ThreadId(56) ProcessJob::process{job_id=66c76ef9fe1bd0ac3bd2f146}: scuffle_image_processor::worker::process: image-processor/src/worker/process/mod.rs:115: starting job
[image-processor/src/worker/process/encoder/libavif.rs:104:4] frame.image.width() = 64
[image-processor/src/worker/process/encoder/libavif.rs:104:4] frame.image.height() = 20
2024-08-22T17:01:46.975251092+00:00 INFO ThreadId(56) ProcessJob::process{job_id=66c76ef9fe1bd0ac3bd2f146}: scuffle_image_processor::worker::process: image-processor/src/worker/process/mod.rs:163: job completed in 413.24328ms
2024-08-22T17:01:53.776022865+00:00 INFO ThreadId(03) process_image:process_image: scuffle_image_processor::management: image-processor/src/management/mod.rs:33: new process image request
2024-08-22T17:01:54.595982504+00:00 INFO ThreadId(56) ProcessJob::process{job_id=66c76f01fe1bd0ac3bd2f147}: scuffle_image_processor::worker::process: image-processor/src/worker/process/mod.rs:115: starting job
[image-processor/src/worker/process/encoder/libavif.rs:104:4] frame.image.width() = 96
[image-processor/src/worker/process/encoder/libavif.rs:104:4] frame.image.height() = 30
2024-08-22T17:01:55.023856008+00:00 INFO ThreadId(56) ProcessJob::process{job_id=66c76f01fe1bd0ac3bd2f147}: scuffle_image_processor::worker::process: image-processor/src/worker/process/mod.rs:163: job completed in 427.826163ms

it fails to encode the image when its 32x10 but succeeds when its 64x20
what why
So a fix for this would be a resize before process?
idk why the small image does not work

also only an issue on the animation encoder
@south flare how is framerate determined?
it's still snapped to 25 fps and 33.333 fps right?
but is it rounded up/down/nearest?
i just scrolled up and what 
yes. Do you like it?
how even
the timing of each frame is how the effective frame rate is determined
and vice versa, when encoding
how do you even go about making something like that
skill
okay wait what is ur question
how do we calculate the frame timings?
directly from the input image we do not change them
my question is how the actual animation is made 
like how you go from nothing to cool moving blobs of color like in that file
was a question for anson
idk abt that that isnt a dev thing
fair enough 
it seems
i got the resize right this time
and it results in a smaller file
the gif is big
but actually looks okay
ill investigate why libavif doesnt like files with small width/height
looks sick af
so only gifs will be snapped to gif timings?
10 ms intervals
drop frames from the gifs?
yes
so the avif and webp can be 60 fps?
sick
could the dropped frames also be responsible for the glitchy rendering in discord?
missing frames of changed pixels
probably not tbh
because discord-encoded gifs have that same problem
no
that is the old processor
the new processor is not deployed
and that is just becasue discord engineers are retards
sick sick
and dont know how to implement gif encoding / decoding correctly
i still hate that webp and avif dont fucking embed on discord
it's dumb

same for opus files not being able to be previewed in-line
and other file types
even though voice messages are just opus files
They use electron
oh and h.265 encoded videos don't embed either
They removed the feature
I know people that have switched to Revolt entirely
no more discord
it's not perfect, but it's surprisingly good
can be self-hosted
@south flare so why are 7tv's avifs twice the size of mine?
Wym which one s
I told u the new image processor is not deployed
so the old one is very old
the encoders have likely improved and thats why when i reencoded it for u just now i got 50kb
isnt that like amazing or
so do we
well yeah but its at least very small file
yes
plus thats like a name paint gif its not like you're ever supposed to see that in full quality so who cares
webp is 345kb
sorta true
ideally paints could have different qualities load based on the needed size, like emotes
but when are names ever large enough for that to matter
even then most of the image is being obscured and is only visible through the letters
the only way you'd notice the quality loss in the image is opening the image itself really
right
every paint usually uses the 1x emote size anyway

that's why they look so bad 
mf watches twitch on 400% zoom
anson with his browser zoomed in to 500x
same joke
also chatterino wont even load the paints if the file is too big
the twitchcon paris paint looks like white noise
same thing happens with emote preview
it just gives you 2x preview at most
okay
so the bug with avif
is actually a big with rav1e
it seems that if i use libaom it works

here is an example of an emote https://7tv.app/emotes/66b631194ced7335aac1c84a
the 4x size is 1.2mb
so it'll display the 3x one only?
chatterino just shows the 2x
o
even less
cause the 3x is 887

that image
512kb??
the super complex one
why?
would need some testing i guess 
wait a minute this is the 7tv version of chatterino right? cuz it doesn't show name paints on normal chatterino?
yes
i wonder if i can find the file limit in the sorce code 
we dont use avifs for anything
L

using libaom is faster + doesnt have the issue with the sizing
job completed in 2.71011696s
the file is bigger tho
but it encodes much faster
hmm
trying to figure out where in the chatterino7 source it mentions anything about emote/paint sizes to know when to fallback to smaller 
if its even handled there in the first place
not saying its a c7 issue specifically its just that its the one you were using in screenshot
since namepaint is visible

i wonder if its actually something that happens on the 7tv api when passing the emotes/paints to chatterino or whatever 

weird considering the fact that from the looks of it, chatterino DOES try to get up to 4x
so like what the fuck happens to 4x and 3x
okay its completely random

cause this one displays correctly for example
but it never fixes itself
if an emote is fucked it just stays at 2x preview
fucking weird
still bigger file size seems to fail more often

@strange owl @rigid narwhal
@rugged perch btw https://7tv.app/emotes/66c6739cc66164d0fc0c3cc8
- this aint moving
- can I delete it already?
actually I'll unlist and you can delete when not needed
cause there are multiple
yes
MY BADGE
Yes if you see any of these test ones you can delete them 
holy shit, you guys found out so much stuff regarding the avif problem while I was away
also congrats on contributor ftk 

Thank you
I feel the same

yea it wasn't a big issue apperantly since it was just a matter of resizing the AVIF file i guess
did you guys sort out the avif issue only or those broken gifs as well?
because I just remembered this exists
we can't fix the gif format

1 bit alpha, basically
these appear to have a stutter right as they loop, that wasn't there in the original
true, the transparency is a gif limitation in general
no
"variable transparency" is just a way to try to explain the fact that gifs don't have an alpha channel
not a limitation of 7tv's implementation
so it's not even that we dont support it, it just doesnt exist?
right
gifs can have a maximum of 256 colors in their palette, and one of them can be designated as transparent
so it's either a color, or transparent
and just like that we also have another emote that couldn't be uploaded, this time an animated png https://gachi.gay/BTqUh (sharing through that link, because discord breaks the file)
true 
I think that one was 30 fps
but for each frame
I don't specify frame timings
I give it a sequence of images and specify a frame rate
because I'm not insane
(not THAT insane)
I can run it through avifdec
it shows duration 0.03 (1 timescales)
weirdness discovered
your converted versions have 150 frames, each set to 0.04 (40 timescales)
except the first frame, which is 1 timescales
on MothSanityCheck (assuming that's the one that these came from) it's 150 frames, each at 0.04 duration and 1 timescales
here's the data I can find if it helps :
File Name : ezgif.com-resize 2 (1).png
Directory : .
File Size : 1859 kB
Zone Identifier : Exists
File Modification Date/Time : 2024:08:23 01:36:33+03:00
File Access Date/Time : 2024:08:23 01:37:44+03:00
File Creation Date/Time : 2024:08:23 01:37:37+03:00
File Permissions : -rw-rw-rw-
File Type : APNG
File Type Extension : png
MIME Type : image/apng
Image Width : 127
Image Height : 127
Bit Depth : 8
Color Type : RGB with Alpha
Compression : Deflate/Inflate
Filter : Adaptive
Interlace : Noninterlaced
Animation Frames : 112
Animation Plays : inf
Software : ezgif.com
Comment : PNG edited with https://ezgif.com/resize
Image Size : 127x127
Megapixels : 0.016
I'm checking other ones
because I have one that says it has 180 frames
and I can't figure out why
I think it's the one that I tried 33.333333 fps
which I guess makes sense
I guess it's resampling frames to get a specific framerate
avifdec -i {file} tells me everything I need, I think
I hate working with APNG files. They work in barely any software and are way too big
I remember when discord accepted them as the default sticker's file type
Interestingly enough windows also shows it's bit depth as 32 bit, but I'm not trusting that 
encoding with only ffmpeg (no avifenc) does weird things too
180 frames
man, webp is just such an awful format for this
vp8 ahh codec
why does exiftool say 150 frames = 5 seconds
for a gif
that shouldn't be possible
the gif plays slightly slower than the avif
so it's not being rounded up to 33.3333
I tried avifenc's keyframe feature as well, and it does make larger files
which is odd
just like the webp one
ALTHOUGH it does seem to INCREASE the visual quality
by having keyframes enabled
I put -k 100
which means at least one keyframe every 100 frames
so a slight file size increase but also filesize increase
ok I made a 25 fps gif and it's WAY slower than the "30 fps" gif
I've always wondered if gifski might be swapping between 30 ms and 20 ms frame timings to achieve the given frame rate
it looks like it does
very cool
@south flare you use gifski too right?
Do you quantize the framerates or allow it to do this form of "dithering"?
because it's kinda based
I'm so confused
I can't create an avif with normal duration in exiftool anymore
they're all many millions of days
Ok so a 30 FPS webp file has a frame duration in the pattern of 33, 33, 34 (repeating), and when uploaded to 7TV, the processor converts them all to a frame duration of 30, which is 33.3333 FPS. This applies to the webp, avif, and gif outputs.
I still can't figure out how I made an avif that uploads, but the working files still work when uploaded. The only difference I can see is that they're 25 FPS. But when I try to make a new 25 FPS avif, they won't upload.
ansonx10 feels rested: ๐ ๐ค (7h, 34m ago)
Uploading as a gif preserves the exact frame timings for all 3 converted formats
try another fps
could that work?
for the AVIF at least
I've tried 25, 30, and 33.33333
What else should I try?
I did try 60 but I forget the result
doesn't work

the sanity check one still works
I will show you da way
pretty sure the only thing I did was remove the --fps flag from avif
leaving only the ffmpeg -r flag
but I can't replicate it
it seemed to default to 25 fps
but you setting the flag to 25 fps doesn't work
tf....
@paper token ok send me 2 files
Send me the sanity check without the --fps flag, and send me the one where you add the fps to be 25
well
send me the AVIF that has the --fps flag with it beind 25 fps
I made one just now
I tried setting it back to what I remembered it was, which was yuva444p

I had been experimenting with yuv444p, because I don't need an alpha channel
i wanna compare both
for what is this channel?




6Head
does 7tv got some documentation? I would like to integrate 7tv with an account to our site
Noted, ty

Hello, how I display the 7tv colors on my website? I have the color "-5635841" from the api but I don't know how I display this. Can anyone help me?
I suggest using this!! 
Thank you!
https://7tv.fishkido.tv/ if anyone needs to fetch their paint 
add a way to use twitch id 
Thanks for the feedback. I'll look into doing this

also that's a little mistake others have made before, some radial paints like tie-dye and strawberry creme have the repeat flag enabled which means you have to use repeating-radial-gradient() instead of just radial-gradient() for their gradient.
if you dont do that rthe paint gets rendered wrong
left is how its currently being rendered with just radial-gradient
and right with repeating
oh i guess there are also linear paints with it but you have that implemented already
Hmm ok ill look into this aswell, thanks for your awesome feedback
If you recommend anything else please share and @ me
How I get a 7tv user by the twitch user id?
u can just use /users/twitch/<twitch id>
I'm planning to add that to my website today
work it for every user or just for registered channels?
if there is a twitch channel connected to a 7tv user
it works
const query = {
operationName: 'GetUserByConnection',
query: `query GetUserByConnection($platform: ConnectionPlatform! $id: String!) {
userByConnection (platform: $platform id: $id) {
id
type
username
style {
paint { name id }
badge { name id }
}
cosmetics {
id
kind
selected
}
}
}`,
variables: {
platform,
id: twitchID
}
};
gets paint by platform id (twitch) so you dont need to make two requests
any updates on the new website / api v4?
the new kick site sucks ass
They made it so hard to modify elements on that site, I suppose 7TV Will be a pain in the ass to be fixed on their new site
Like the devs are just trying so hard to now allow other devs to do whatever, it's so lame
is it live yet?
or just the preview version
it is











