Fixed various video embedding bugs.

This commit is contained in:
flash 2023-01-26 22:51:33 +00:00
parent 9dae77628d
commit 48ce465893
8 changed files with 140 additions and 32 deletions

View file

@ -89,10 +89,12 @@
font-weight: 400;
line-height: 1.1em;
margin-bottom: 5px;
word-break: break-word;
}
.embedph-info-desc {
line-height: 1.4em;
margin: .5em 0;
word-break: break-word;
}
.embedph-info-site {
font-size: .9em;

View file

@ -129,31 +129,70 @@ Misuzu.handleEmbeds = function() {
if(embeds.length > 0) {
$as(embeds);
const uiharu = new Uiharu(UIHARU_API)
elems = new Map(embeds.map(function(elem) { return [elem.dataset.mszEmbedUrl, elem]; }));
const uiharu = new Uiharu(UIHARU_API),
elems = new Map;
for(const elem of embeds) {
let cleanUrl = elem.dataset.mszEmbedUrl.replace(/ /, '%20');
if(cleanUrl.indexOf('http://') !== 0 && cleanUrl.indexOf('https://') !== 0) {
elem.textContent = elem.dataset.mszEmbedUrl;
continue;
}
elem.textContent = 'Loading...';
if(elems.has(cleanUrl))
elems.get(cleanUrl).push(elem);
else
elems.set(cleanUrl, [elem]);
}
uiharu.lookupMany(Array.from(elems.keys()), function(resp) {
if(resp.results === undefined)
return; // rip
for(const result of resp.results) {
let elemList = elems.get(result.url);
const replaceWithUrl = function() {
for(let i = 0; i < elemList.length; ++i) {
let body = $e({
tag: 'a',
attrs: {
className: 'link',
href: result.url,
target: '_blank',
rel: 'noopener noreferrer',
},
child: result.url
});
$ib(elemList[i], body);
$r(elemList[i]);
elemList[i] = body;
}
};
if(result.error) {
replaceWithUrl();
console.error(result.error);
continue;
}
if(result.info.title === undefined) {
replaceWithUrl();
console.warn('Media is no longer available.');
continue;
}
let elem = elems.get(result.url);
(function(elem, info) {
const replaceElement = function(body) {
$ib(elem, body);
$r(elem);
elem = body;
(function(elemList, info) {
const replaceElement = function(bodyInfo) {
for(let i = 0; i < elemList.length; ++i) {
let body = $e(bodyInfo);
$ib(elemList[i], body);
$r(elemList[i]);
elemList[i] = body;
}
};
const createEmbedPH = function(type, info, onclick, width, height) {
@ -208,7 +247,7 @@ Misuzu.handleEmbeds = function() {
bgElem = {};
}
return $e({
return {
attrs: {
href: 'javascript:void(0);',
className: ('embedph embedph-' + type),
@ -284,7 +323,7 @@ Misuzu.handleEmbeds = function() {
],
},
],
});
};
};
if(info.type === 'youtube:video') {
@ -301,7 +340,7 @@ Misuzu.handleEmbeds = function() {
}
replaceElement(createEmbedPH('youtube', info, function() {
replaceElement($e({
replaceElement({
attrs: {
className: 'embed embed-youtube',
},
@ -314,7 +353,7 @@ Misuzu.handleEmbeds = function() {
src: embedUrl,
},
},
}));
});
}));
} else if(info.type === 'niconico:video') {
let embedUrl = 'https://embed.nicovideo.jp/watch/' + info.nicovideo_video_id + '/script?w=100%25&h=100%25&autoplay=1';
@ -323,7 +362,7 @@ Misuzu.handleEmbeds = function() {
embedUrl += '&from=' + encodeURIComponent(info.nicovideo_start_time);
replaceElement(createEmbedPH('nicovideo', info, function() {
replaceElement($e({
replaceElement({
attrs: {
className: 'embed embed-nicovideo',
},
@ -334,9 +373,11 @@ Misuzu.handleEmbeds = function() {
src: embedUrl,
},
},
}));
});
}));
} else if(info.type === 'media') {
// todo: proxying
// think uiharu will just serve as the camo system
if(info.is_video) {
let width = info.width,
height = info.height;
@ -360,7 +401,7 @@ Misuzu.handleEmbeds = function() {
}
replaceElement(createEmbedPH('external', info, function() {
replaceElement($e({
replaceElement({
attrs: {
className: 'embed embed-external',
},
@ -376,13 +417,40 @@ Misuzu.handleEmbeds = function() {
},
},
},
}));
});
}, width, height));
} else if(info.is_audio) {
// coming someday
// need dedicated audio placeholder and a player frame that includes the cover art
replaceElement(createEmbedPH('external', info, function() {
replaceElement({
attrs: {
className: 'embed embed-external',
},
child: {
tag: 'audio',
attrs: {
autoplay: 'autoplay',
controls: 'controls',
src: info.url,
},
},
});
}, '300px', '300px'));
} else if(info.is_image) {
replaceElement({
tag: 'img',
attrs: {
src: info.url,
alt: info.url,
style: {
maxWidth: '100%',
maxHeight: '900px',
},
},
});
}
}
})(elem, result.info);
})(elemList, result.info);
}
});
}

View file

@ -1,5 +1,5 @@
const Uiharu = function(apiUrl) {
const maxBatchSize = 5;
const maxBatchSize = 4;
const lookupOneUrl = apiUrl + '/metadata',
lookupManyUrl = apiUrl + '/metadata/batch';

@ -1 +1 @@
Subproject commit fbe4fe18decd502a0ca15ffe8a7c3b2d847349d5
Subproject commit 1a8344c1c31cb62726305d079384045582315f64

View file

@ -13,10 +13,13 @@ final class AudioTag extends BBCodeTag {
if(empty($url['scheme']) || !in_array(mb_strtolower($url['scheme']), ['http', 'https'], true))
return $matches[0];
//return sprintf('<span class="js-msz-embed-media" data-msz-embed-url="%1$s"><a href="%1$s" class="link" rel="noopener noreferrer">%1$s</a></span>', $matches[1]);
// return sprintf(
// '<span class="js-msz-embed-media" data-msz-embed-url="%1$s"></span>'
// . '<noscript><a href="%1$s" class="link" rel="noopener noreferrer">%1$s</a></noscript>',
// $matches[1]
// );
$mediaUrl = $matches[1];
return "<audio controls src='{$mediaUrl}'></audio>";
return "<audio controls src='{$matches[1]}'></audio>";
},
$text
);

View file

@ -6,9 +6,18 @@ use Misuzu\Parsers\BBCode\BBCodeTag;
final class ImageTag extends BBCodeTag {
public function parseText(string $text): string {
return preg_replace_callback("/\[img\]((?:https?:\/\/).+?)\[\/img\]/", function ($matches) {
//$mediaUrl = url_proxy_media($matches[1]);
$mediaUrl = $matches[1];
return sprintf('<img src="%s" alt="%s" style="max-width:100%%;max-height:900px;">', $mediaUrl, $matches[1]);
$url = parse_url($matches[1]);
if(empty($url['scheme']) || !in_array(mb_strtolower($url['scheme']), ['http', 'https'], true))
return $matches[0];
// return sprintf(
// '<span class="js-msz-embed-media" data-msz-embed-url="%1$s"></span>'
// . '<noscript><img src="%1$s" alt="%1$s" style="max-width:100%%;max-height:900px;"></noscript>',
// $matches[1]
// );
return sprintf('<img src="%1$s" alt="%1$s" style="max-width:100%%;max-height:900px;">', $matches[1]);
}, $text);
}
}

View file

@ -13,7 +13,11 @@ final class VideoTag extends BBCodeTag {
if(empty($url['scheme']) || !in_array(mb_strtolower($url['scheme']), ['http', 'https'], true))
return $matches[0];
return sprintf('<span class="js-msz-embed-media" data-msz-embed-url="%1$s"><a href="%1$s" class="link" rel="noopener noreferrer">%1$s</a></span>', $matches[1]);
return sprintf(
'<span class="js-msz-embed-media" data-msz-embed-url="%1$s"></span>'
. '<noscript><a href="%1$s" class="link" rel="noopener noreferrer">%1$s</a></noscript>',
$matches[1]
);
},
$text
);

View file

@ -13,12 +13,34 @@ class MarkdownParser extends Parsedown implements ParserInterface {
}
protected function inlineImage($excerpt) {
$object = parent::inlineImage($excerpt);
// remove this line when media detection works entirely as expected
return parent::inlineImage($excerpt);
//if(!empty($object['element']['attributes']['src']) && !is_local_url($object['element']['attributes']['src'])) {
// $object['element']['attributes']['src'] = url_proxy_media($object['element']['attributes']['src']);
//}
if(!isset($excerpt['text'][1]) || $excerpt['text'][1] !== '[')
return;
return $object;
$excerpt['text'] = substr($excerpt['text'], 1);
$link = $this->inlineLink($excerpt);
if($link === null)
return;
$inline = [
'extent' => $link['extent'] + 1,
'element' => [
'name' => 'span',
'attributes' => [
'class' => 'js-msz-embed-media',
'data-msz-embed-url' => $link['element']['attributes']['href'],
'data-msz-embed-alt' => $link['element']['text'],
],
],
];
$inline['element']['attributes'] += $link['element']['attributes'];
unset($inline['element']['attributes']['href']);
return $inline;
}
}