问题描述
有没有办法在 twitch.tv 以外的网站上使用例如 BetterTTV 或 FranzerFaceZ (FFZ) 来替换表情?
我想在 twitch 上显示在线提醒(通过浏览器源代码实现)。发送的消息通常包含诸如 OMEGALUL 或 PogU 之类的表情。
我知道我可以下载图像并替换字符串中的表情符号。这已经在起作用了。但是,总是缺少一些表情(因为我需要全部实现)。
那么有没有办法在 twitch 以外的页面上使用其中一个表情替换系统?
例如这条消息
Hey PogU :)
应该变成
Hey <img src="...."> :)
我没有找到任何可能性,但至少对于 BetterTTV 来说,有一个选项可以实现 javascript 文件,因为必须有一种方法。
解决方法
不是我最初的意图,因为这仅限于我下载的表情,但我的快速和肮脏的方法是(使用 Laravel - 所以纯 php 将没有像 storage_path
这样的助手或 dd
):
注意:这些下载需要相当长的时间。因此,如果您只是使用例如 30 秒 php 超时 运行它们,则会遇到超时。因此,要么从 CLI 启动它,要么将时间限制设置为无限(例如 set_time_limit(0);
或在 php.ini 中:max_execution_time = 0
)
第一步:下载表情
替代方案 1:BTTV
<?php
// Download emotes first and put them into a json (multiple times using offset): https://api.betterttv.net/3/emotes/shared/top?offset=1199&limit=100
// Merge them into one emotes.json file
function downloadBTTV() {
$emotes = json_decode(file_get_contents(storage_path('emotes.json')),false,512,JSON_THROW_ON_ERROR);
$used_filenames = [];
$used_emotes = [];
foreach($emotes as $emote) {
try{
$url = 'https://cdn.betterttv.net/emote/' . $emote->emote->id . '/1x';
$filename = $emote->emote->code . '.' . $emote->emote->imageType;
if(!isset($used_filenames[$filename])) {
$used_filenames[$filename] = 0;
}
$used_filenames[$filename]++;
$full_filename = storage_path('emotes/' . $filename);
if(!is_file($full_filename) && in_array($emotes->emote->code,$used_emotes)) {
file_put_contents($full_filename,file_get_contents($url));
$used_emotes[] = $emote->emote->code;
}
} catch(\Exception $e) {
dd(get_defined_vars(),$emote);
}
}
}
替代方案 #2:FFZ
1) 获取 FFZ 图像 ID
// Open page https://www.frankerfacez.com/emoticons/wall?q=&sort=count-desc&days=0 and scroll a lot down
// Then execute the following js code on the page
var emotes = {};
document.querySelectorAll('a.thumbnail').forEach(function(el,index){
var href = el.getAttribute('href');
var name = el.querySelector('h3').textContent.toLowerCase();
var id = href.substr(href.lastIndexOf("/")+1,href.indexOf('-') - href.lastIndexOf('/') - 1);
if(!emotes.hasOwnProperty(name)) {
emotes[name] = id;
}
});
console.log(Object.keys(emotes).length)
copy(emotes);
2) 用 PHP 下载图片
<?php
// 2a) Create a variable like that from the clipboard (copied in javascript in step 1)
$ffz_emotes_json = <<<'EOL'
{
"pog": "210748","omegalul": "128054",//...
}
EOL;
function downloadFFZ() {
global $ffz_emotes_json;
$emotes = json_decode($ffz_emotes_json,true,JSON_THROW_ON_ERROR);
$new_emotes = [];
$skipped_emotes = [];
foreach($emotes as $emote => $id) {
$url = 'https://cdn.frankerfacez.com/emoticon/' . $id . '/1';
$filename = $emote . '.png';
$filename_gif = $emote . '.gif';
$full_filename_png = storage_path('emotes/' . $filename);
$full_filename_gif = storage_path('emotes/' . $filename_gif);
if(!is_file($full_filename_png) && !is_file($full_filename_gif) ) {
file_put_contents($full_filename_png,file_get_contents($url));
$new_emotes[] = $emote;
} else {
$skipped_emotes[] = $emote;
}
}
dd($new_emotes,$skipped_emotes);
}
第 2 步:创建表情字典
现在,您已将所有这些图像存储在存储路径中,我们需要创建一个字典来查找它们(在这种方法中,它是通过 javascript 完成的)。
<?php
function generateEmotesJS()
{
$files = glob(public_path('img/emotes/*'));
echo "window.EMOTES = {\n";
/** @var DirectoryIterator $fileInfo */
foreach (new DirectoryIterator(public_path('img/emotes/*')) as $fileInfo) {
if($fileInfo->isDot()) continue;
echo ' "' . $fileInfo->getBasename('.' .$fileInfo->getExtension()) .'": "' . $fileInfo->getExtension() . "\",\n";
}
echo "};";
}
// store this output in your javascript file
第 2 步:替换消息中的表情
// You already have something like this in your file from the previous step
window.EMOTES = {
"!treat": "png","(ditto)": "gif","02ayaya": "png",// ...
};
// call this function to replace the emotes:
window.replaceEmotes = function(message)
{
// https://stackoverflow.com/a/59664804/936284
return message.split(/([\W])/).map(function(el,index){
if(index % 2 === 0) {
lower = el.toLowerCase();
if(EMOTES.hasOwnProperty(lower)) {
return '<img src="/img/emotes/' + lower + '.' + EMOTES[lower] + '" alt="' + el + '">';
}
}
return el;
}).join("")
}
// You can now call this:
console.log(replaceEmotes('Hey PogU :)'));
// Returns: Hey <img src="/img/emotes/pogu.png" alt="PogU"> :)
console.log(replaceEmotes("Hey ho OMEGALUL"));
// Returns Hey ho <img src="/img/emotes/omegalul.png" alt="OMEGALUL">
console.log(replaceEmotes("Test Kappa\nTest > all <3"));
// Returns: Test <img src="/img/emotes/kappa.png" alt="Kappa">
// Test > all <3
就像我说的,又快又脏。如果你有时间,你肯定会找到更好的方法。也许对 chrome 扩展进行逆向工程以进行替换更有意义 ;)