Uploading animated GIFs
You can use any of our public icons when creating your content, but you can also upload your own animated GIFs.
In this example, we’ll be uploading this animated GIF .
The animated GIF upload process works exactly the same as uploading custom icons
Preparing your animated GIF
Section titled “Preparing your animated GIF”Here are the requirements for animated GIFs
- Must be exactly 16×16 pixels in dimensions
- Must be in GIF or PNG format
Unlike regular icons, animated GIFs cannot use autoConvert=true
because the conversion process would remove the animation and convert it to a static PNG.
If your GIF doesn’t meet these requirements, you’ll receive a validation error.
Upload your animated GIF
Section titled “Upload your animated GIF”import { readFileSync } from 'node:fs';const gifBuffer = readFileSync('./animated-icon.gif');
const gifFile = new Blob([gifBuffer], { type: 'image/gif' });
const url = `https://api.yotoplay.com/media/displayIcons/user/me/upload?autoConvert=false&filename=animated-icon`;
const uploadResponse = await fetch(url, { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'image/gif', }, body: gifFile,});
const uploadResult = await uploadResponse.json();
Upload parameters for animated GIFs
Section titled “Upload parameters for animated GIFs”When uploading animated GIFs, you must use these specific parameters:
-
autoConvert
(boolean): Must be set tofalse
for animated GIFs. Whenfalse
, the server will validate that your GIF is exactly 16×16 pixels and preserve the animation. -
filename
(string): Optional custom filename for your animated icon. The.gif
extension will be automatically determined from the uploaded file’s MIME type.
If your GIF doesn’t meet these requirements, you’ll receive a validation error.
Using your uploaded animated GIF
Section titled “Using your uploaded animated GIF”Once uploaded successfully, you’ll receive a response containing:
{ "displayIcon": { "mediaId": "XBkuY6DBFn5iRfFS6nV6CTWaCrEvBOOX8nzV9Y64h8I", "userId": "auth0|userHash", "displayIconId": "683736c62fd7c5cd177d206f", "url": "https://media-secure.aws.com/icons/mlWc6s-JG", "new": true }}
Now you can use the mediaId
whenever you need to reference the animated GIF icon.
Tips for creating animated GIF icons
Section titled “Tips for creating animated GIF icons”- Keep animations simple and subtle
- Use a limited color palette so that it displays nicely on your Yoto player
- Consider the animation speed, too fast can be distracting, and too slow can look laggy
Here’s an example of a complete workflow:
import { readFileSync } from 'node:fs';
export async function createAnimatedGifCard({ iconPath = './animated-icon.gif', filename = 'animated-icon', title = 'My Playlist with Animated Icon', cardId, accessToken,}) { // Read the animated GIF file // Note: Your GIF must be exactly 16x16 pixels const gifBuffer = readFileSync(iconPath);
// Create a Blob from the buffer const gifFile = new Blob([gifBuffer], { type: 'image/gif' });
// Set up the upload URL with required parameters const url = `https://api.yotoplay.com/media/displayIcons/user/me/upload?autoConvert=false&filename=${filename}`;
console.log('Uploading animated GIF...');
// Upload the file const uploadResponse = await fetch(url, { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'image/gif', }, body: gifFile, });
if (!uploadResponse.ok) { const errorText = await uploadResponse.text(); throw new Error(`Upload failed: ${uploadResponse.status} ${errorText}`); }
const uploadResult = await uploadResponse.json();
// The response should contain the mediaId const { mediaId } = uploadResult.displayIcon;
console.log('Animated GIF uploaded successfully:', { mediaId, });
// Step 2: Create streaming card content using the uploaded animated GIF // Here, we're making a streaming playlist for simplicity const chapters = [ { key: '01', title: title, overlayLabel: '1', tracks: [ { key: '01', type: 'stream', format: 'mp3', title: title, trackUrl: 'https://yoto.dev/music/autumn-3.mp3', display: { icon16x16: `yoto:#${mediaId}`, // Using the uploaded animated GIF }, }, ], display: { icon16x16: `yoto:#${mediaId}`, // Using the uploaded animated GIF }, }, ];
const content = { title, content: { chapters }, metadata: { description: `Streaming card with animated ${filename} icon`, }, };
if (cardId) { // specify a cardId to update an existing card content.cardId = cardId; }
// Create the card with the animated GIF icon const createResponse = await fetch('https://api.yotoplay.com/content', { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json', }, body: JSON.stringify(content), });
const card = await createResponse.json();
console.log('Streaming card created successfully with animated GIF icon!');
return card;}