import i18next from 'i18next';
import { Constants } from '../constants';
import { Experiment, experimentCheck } from '../experiments';
import { handleQuote } from '../helpers/quote';
const getGIFTranscodeDomain = (twitterId: string): string | null => {
const gifTranscoderList = Constants.GIF_TRANSCODE_DOMAIN_LIST;
if (gifTranscoderList.length === 0) {
return null;
}
let hash = 0;
for (let i = 0; i < twitterId.length; i++) {
const char = twitterId.charCodeAt(i);
hash = (hash << 5) - hash + char;
}
return gifTranscoderList[Math.abs(hash) % gifTranscoderList.length];
};
export const renderVideo = (
properties: RenderProperties,
video: APIVideo
): ResponseInstructions => {
const { status, userAgent, text } = properties;
const instructions: ResponseInstructions = { addHeaders: [] };
const all = status.media?.all as APIMedia[];
/* This fix is specific to Discord not wanting to render videos that are too large,
or rendering low quality videos too small.
Basically, our solution is to cut the dimensions in half if the video is too big (> 1080p),
or double them if it's too small. (<400p)
We check both height and width so we can apply this to both horizontal and vertical videos equally*/
let sizeMultiplier = 1;
if (video.width > 1920 || video.height > 1920) {
sizeMultiplier = 0.5;
}
if (video.width < 400 && video.height < 400) {
sizeMultiplier = 2;
}
/* Like photos when picking a specific one (not using mosaic),
we'll put an indicator if there are more than one video */
if (all && all.length > 1 && (userAgent?.indexOf('Telegram') ?? 0) > -1) {
const baseString =
all.length === status.media?.videos?.length
? i18next.t('videoCount')
: i18next.t('mediaCount');
const videoCounter = baseString.format({
number: String(all.indexOf(video) + 1),
total: String(all.length)
});
instructions.siteName = `${Constants.BRANDING_NAME} - ${videoCounter}`;
}
instructions.authorText = status.translation?.text || text || '';
if (instructions.authorText.length < 40 && status.quote) {
instructions.authorText += `\n${handleQuote(status.quote)}`;
}
let url = video.url;
if (
experimentCheck(Experiment.TRANSCODE_GIFS, !!Constants.GIF_TRANSCODE_DOMAIN_LIST) &&
!userAgent?.includes('Telegram') &&
video.type === 'gif'
) {
url = video.url.replace(
Constants.TWITTER_VIDEO_BASE,
`https://${getGIFTranscodeDomain(status.id)}`
);
console.log('We passed checks for transcoding GIFs, feeding embed url', url);
}
if (
userAgent?.includes('Discord') &&
experimentCheck(Experiment.DISCORD_VIDEO_REDIRECT_WORKAROUND, !!Constants.API_HOST_LIST)
) {
url = `https://${Constants.API_HOST_LIST[0]}/2/hit?url=${encodeURIComponent(url)}`;
}
/* Push the raw video-related headers */
instructions.addHeaders = [
``,
``,
``,
``,
``,
``,
``,
``,
``,
``,
``
];
return instructions;
};