- 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.
|
||||
|
||||
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.
|
||||
|
||||
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();
|
||||
$youtube_timestamp_candidates = media_youtube_timestamp_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);
|
||||
|
||||
$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>
|
||||
<p class="hint">
|
||||
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)) ?>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
+43
-2
@@ -543,8 +543,12 @@ function media_imgur_page_url(string $url): string {
|
||||
}
|
||||
|
||||
function media_imgur_embed_url(string $url): string {
|
||||
$page = media_imgur_page_url($url);
|
||||
return $page !== '' ? rtrim($page, '/') . '/embed' : '';
|
||||
$path = media_imgur_path_from_url($url);
|
||||
if ($path === '') return '';
|
||||
return media_append_query(public_url_path('/provider_embed.php'), [
|
||||
'provider' => 'imgur',
|
||||
'id' => $path,
|
||||
]);
|
||||
}
|
||||
|
||||
function media_normalize_datetime(string $value): string {
|
||||
@@ -677,6 +681,26 @@ function media_view_count_from_html(string $html): int {
|
||||
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 {
|
||||
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');
|
||||
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']);
|
||||
}
|
||||
|
||||
@@ -784,6 +812,19 @@ function media_external_view_count_candidate_count(): int {
|
||||
")->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 {
|
||||
$result = [
|
||||
'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