- Fixed the Imgur embed path.
Imgur now uses a local wrapper page, [provider_embed.php](/Users/tyemeclifford/Documents/GH/mediaplayer/provider_embed.php), that renders Imgur’s official blockquote + https://s.imgur.com/min/embed.js snippet instead of trying to iframe Imgur directly. That should avoid the “refuses to connect” issue for albums, galleries, images, GIFs, GIFV, and videos. Also updated: [includes/db.php](/Users/tyemeclifford/Documents/GH/mediaplayer/includes/db.php): Imgur embed URLs now point to the wrapper, and Imgur view-count scraping has dedicated fallback patterns. [admin/index.php](/Users/tyemeclifford/Documents/GH/mediaplayer/admin/index.php): Upkeeping → Correct Views now explicitly counts Imgur-backed items in the candidate summary. [README.md](/Users/tyemeclifford/Documents/GH/mediaplayer/README.md): documented the Imgur wrapper behavior.
This commit is contained in:
@@ -79,6 +79,8 @@ Styled to match the existing `gate.php` / `index.php` dark theme exactly.
|
|||||||
|
|
||||||
External URLs must use `http://` or `https://`. Uploaded files and remote URLs can be mixed on the same video. Recognized provider URLs such as YouTube, Vimeo, Dailymotion, Imgur, Twitch, Facebook, TikTok, Instagram, X/Twitter, SoundCloud, Spotify, Google Drive, Wistia, Streamable, and Loom render through their embed players.
|
External URLs must use `http://` or `https://`. Uploaded files and remote URLs can be mixed on the same video. Recognized provider URLs such as YouTube, Vimeo, Dailymotion, Imgur, Twitch, Facebook, TikTok, Instagram, X/Twitter, SoundCloud, Spotify, Google Drive, Wistia, Streamable, and Loom render through their embed players.
|
||||||
|
|
||||||
|
Imgur links use the official Imgur embed script inside a local wrapper, so album, gallery, image, GIF, GIFV, and video URLs can render without direct iframe blocking.
|
||||||
|
|
||||||
When adding an external URL, the admin form can fetch title, description, duration, thumbnail metadata, and readable provider view counts through oEmbed, page metadata, and JSON-LD. The save action repeats the metadata lookup as a fallback, so blank titles can be filled from supported external pages even if the browser autofill was not used.
|
When adding an external URL, the admin form can fetch title, description, duration, thumbnail metadata, and readable provider view counts through oEmbed, page metadata, and JSON-LD. The save action repeats the metadata lookup as a fallback, so blank titles can be filled from supported external pages even if the browser autofill was not used.
|
||||||
|
|
||||||
If no thumbnail image is uploaded, the add/edit forms can auto-grab one from the first supported source. YouTube and Dailymotion use direct thumbnail URLs; Vimeo, Wistia, TikTok, SoundCloud, and Spotify use oEmbed when available. Local uploaded videos can generate a first-frame thumbnail when `ffmpeg` is installed on the server.
|
If no thumbnail image is uploaded, the add/edit forms can auto-grab one from the first supported source. YouTube and Dailymotion use direct thumbnail URLs; Vimeo, Wistia, TikTok, SoundCloud, and Spotify use oEmbed when available. Local uploaded videos can generate a first-frame thumbnail when `ffmpeg` is installed on the server.
|
||||||
|
|||||||
+3
-1
@@ -95,6 +95,7 @@ $list_stmt->execute();
|
|||||||
$videos = $list_stmt->fetchAll();
|
$videos = $list_stmt->fetchAll();
|
||||||
$youtube_timestamp_candidates = media_youtube_timestamp_candidate_count();
|
$youtube_timestamp_candidates = media_youtube_timestamp_candidate_count();
|
||||||
$external_view_candidates = media_external_view_count_candidate_count();
|
$external_view_candidates = media_external_view_count_candidate_count();
|
||||||
|
$imgur_view_candidates = media_imgur_view_count_candidate_count();
|
||||||
$admin_total_views = total_video_views(false);
|
$admin_total_views = total_video_views(false);
|
||||||
|
|
||||||
$qs = fn($p) => '?' . http_build_query(array_filter(['q' => $search, 'page' => $p]));
|
$qs = fn($p) => '?' . http_build_query(array_filter(['q' => $search, 'page' => $p]));
|
||||||
@@ -241,7 +242,8 @@ render_head('Admin — TyClifford.com', '
|
|||||||
<h2 class="card-title">Correct external view counts</h2>
|
<h2 class="card-title">Correct external view counts</h2>
|
||||||
<p class="hint">
|
<p class="hint">
|
||||||
Scrapes readable counts from supported providers and adds them to the media-site totals alongside local plays.
|
Scrapes readable counts from supported providers and adds them to the media-site totals alongside local plays.
|
||||||
<?= $external_view_candidates ?> external video<?= $external_view_candidates === 1 ? '' : 's' ?> can be checked.
|
<?= $external_view_candidates ?> external video<?= $external_view_candidates === 1 ? '' : 's' ?> can be checked,
|
||||||
|
including <?= $imgur_view_candidates ?> Imgur-backed item<?= $imgur_view_candidates === 1 ? '' : 's' ?>.
|
||||||
Current database total: <?= h(view_count_label((int)$admin_total_views)) ?>.
|
Current database total: <?= h(view_count_label((int)$admin_total_views)) ?>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+43
-2
@@ -543,8 +543,12 @@ function media_imgur_page_url(string $url): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function media_imgur_embed_url(string $url): string {
|
function media_imgur_embed_url(string $url): string {
|
||||||
$page = media_imgur_page_url($url);
|
$path = media_imgur_path_from_url($url);
|
||||||
return $page !== '' ? rtrim($page, '/') . '/embed' : '';
|
if ($path === '') return '';
|
||||||
|
return media_append_query(public_url_path('/provider_embed.php'), [
|
||||||
|
'provider' => 'imgur',
|
||||||
|
'id' => $path,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function media_normalize_datetime(string $value): string {
|
function media_normalize_datetime(string $value): string {
|
||||||
@@ -677,6 +681,26 @@ function media_view_count_from_html(string $html): int {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function media_imgur_view_count_from_html(string $html): int {
|
||||||
|
$count = media_view_count_from_html($html);
|
||||||
|
if ($count > 0) return $count;
|
||||||
|
|
||||||
|
$html = html_entity_decode($html, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||||
|
$patterns = [
|
||||||
|
'/\bviews?\b[^0-9]{0,80}([0-9][0-9,.\s]*\s*[KMBkmb]?)/i',
|
||||||
|
'/([0-9][0-9,.\s]*\s*[KMBkmb]?)\s+\bviews?\b/i',
|
||||||
|
'/"views_count"\s*:\s*"?(\d+)"?/i',
|
||||||
|
'/"viewsCount"\s*:\s*"?(\d+)"?/i',
|
||||||
|
];
|
||||||
|
foreach ($patterns as $pattern) {
|
||||||
|
if (!preg_match($pattern, $html, $match)) continue;
|
||||||
|
$count = media_count_from_text($match[1]);
|
||||||
|
if ($count > 0) return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
function media_youtube_view_count_from_html(string $html): int {
|
function media_youtube_view_count_from_html(string $html): int {
|
||||||
return media_view_count_from_html($html);
|
return media_view_count_from_html($html);
|
||||||
}
|
}
|
||||||
@@ -708,6 +732,10 @@ function media_external_view_count_from_url(string $url): int {
|
|||||||
$fetch = media_http_get($url, 15, 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8');
|
$fetch = media_http_get($url, 15, 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8');
|
||||||
if ($fetch['body'] === '' || $fetch['error'] !== '') return 0;
|
if ($fetch['body'] === '' || $fetch['error'] !== '') return 0;
|
||||||
|
|
||||||
|
if (media_host_matches($host, 'imgur.com') || media_host_matches($host, 'i.imgur.com')) {
|
||||||
|
return media_imgur_view_count_from_html($fetch['body']);
|
||||||
|
}
|
||||||
|
|
||||||
return media_view_count_from_html($fetch['body']);
|
return media_view_count_from_html($fetch['body']);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,6 +812,19 @@ function media_external_view_count_candidate_count(): int {
|
|||||||
")->fetchColumn();
|
")->fetchColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function media_imgur_view_count_candidate_count(): int {
|
||||||
|
return (int)get_db()->query("
|
||||||
|
SELECT COUNT(DISTINCT v.id)
|
||||||
|
FROM videos v
|
||||||
|
INNER JOIN video_sources vs ON vs.video_id = v.id
|
||||||
|
WHERE vs.source_type='remote'
|
||||||
|
AND (
|
||||||
|
vs.source_url LIKE '%imgur.com%'
|
||||||
|
OR vs.source_url LIKE '%i.imgur.com%'
|
||||||
|
)
|
||||||
|
")->fetchColumn();
|
||||||
|
}
|
||||||
|
|
||||||
function media_restore_external_view_counts(int $limit = 25): array {
|
function media_restore_external_view_counts(int $limit = 25): array {
|
||||||
$result = [
|
$result = [
|
||||||
'checked' => 0,
|
'checked' => 0,
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/includes/db.php';
|
||||||
|
|
||||||
|
$provider = strtolower(trim((string)($_GET['provider'] ?? '')));
|
||||||
|
$id = trim((string)($_GET['id'] ?? ''));
|
||||||
|
|
||||||
|
if ($provider !== 'imgur') {
|
||||||
|
http_response_code(404);
|
||||||
|
exit('Unsupported provider.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = array_values(array_filter(explode('/', $id), 'strlen'));
|
||||||
|
$data_id = '';
|
||||||
|
if (isset($parts[0], $parts[1]) && in_array($parts[0], ['a', 'gallery'], true)) {
|
||||||
|
$clean = media_clean_token($parts[1]);
|
||||||
|
if ($clean !== '') $data_id = $parts[0] . '/' . $clean;
|
||||||
|
} elseif (isset($parts[0])) {
|
||||||
|
$clean = media_clean_token($parts[0]);
|
||||||
|
if ($clean !== '') $data_id = $clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($data_id === '') {
|
||||||
|
http_response_code(400);
|
||||||
|
exit('Invalid Imgur item.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$imgur_url = 'https://imgur.com/' . $data_id;
|
||||||
|
$title = 'Imgur media';
|
||||||
|
?>
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="referrer" content="no-referrer-when-downgrade">
|
||||||
|
<title><?= h($title) ?></title>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin:0;
|
||||||
|
width:100%;
|
||||||
|
min-height:100%;
|
||||||
|
background:#000;
|
||||||
|
color:#fff;
|
||||||
|
font-family:Inter, system-ui, sans-serif;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:center;
|
||||||
|
overflow:auto;
|
||||||
|
}
|
||||||
|
.imgur-embed-pub {
|
||||||
|
width:100%;
|
||||||
|
max-width:100%;
|
||||||
|
margin:0 auto !important;
|
||||||
|
}
|
||||||
|
.imgur-embed-pub iframe {
|
||||||
|
max-width:100% !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<blockquote class="imgur-embed-pub" lang="en" data-id="<?= h($data_id) ?>">
|
||||||
|
<a href="<?= h($imgur_url) ?>" target="_blank" rel="noopener">View on Imgur</a>
|
||||||
|
</blockquote>
|
||||||
|
<script async src="https://s.imgur.com/min/embed.js" charset="utf-8"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user