256 Kilobytes

[PHP] Embed and Autolink Everything with One Function Call: Vimeo, YouTube, DailyMotion, Imgur, and Gyazo

Articles in Server-Side | By August R. Garcia

Published 6 months agoSun, 10 Feb 2019 22:12:12 -0800 | Last update 6 months agoSun, 10 Feb 2019 22:20:37 -0800

As they say, "embedding external videos and images is very nice."

256 views, 0 RAMs, and 1 comment

Here's some code that does the thing specified in the title. It even works, probably.

[PHP] Embed and Autolink Everything with One Function Call: Vimeo, YouTube, DailyMotion, Imgur, and Gyazo

Example Usage

Example Input (HTML String)

<h1>Some Nice Links</h1>
<h2>DailyMotion</h2>
<p>https://www.dailymotion.com/video/xbxbub</p>
<p>https://www.dailymotion.com/video/xg7r8j</p>
<h2>YouTube</h2>
<p>https://www.y outube.com/watch?v=7U9lVjZg-Kg</p>
<p>https://www.y outube.com/watch?v=6zA06imjl1Q</p>
<h2>Vimeo</h2>
<p>https://vimeo.com/33219961</p>
<p>https://vimeo.com/219048822</p>
<h2>Imgur</h2>
<p>https://i.imgur.com/FY1AbSo.gif</p>
<p>https://i.imgur.com/uKnMvyp.jpg</p>
<h3>Albums and Video Clips Don&#39;t Embed:</h3>
<p>https://i.imgur.com/d8skZVO.gifv</p>
<p>https://imgur.com/a/hxsHXtQ</p>
<p>https://imgur.com/a/hxsHXtQ</p>
<h2>Gyazo</h2>
<p>https://i.gyazo.com/5593f3bbe109c38ebf07c16dd25dc4c4.gif</p>
<p>https://i.gyazo.com/40aa155043aa6d75a9a964c9df52fef5.jpg</p>
<h2>Other Links</h2>
<ul>
	<li>https://twitter.com/realdonaldtrump/status/257552283850653696</li>
	<li>https://www.256kilobytes.com/</li>
	<li>https://www.example.com/</li>
</ul>

Example Output (HTML String)

<h1>Some Nice Links<h2>DailyMotion</h2><p><iframe class="auto-embed video dailymotion" src="//www.dailymotion.com/embed/video/xbxbub" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></p><p><iframe class="auto-embed video dailymotion" src="//www.dailymotion.com/embed/video/xg7r8j" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></p><h2>YouTube</h2><p><iframe class="auto-embed video youtube" src="//www.youtube.com/embed/7U9lVjZg-Kg" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></p><p><iframe class="auto-embed video youtube" src="//www.youtube.com/embed/6zA06imjl1Q" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></p><h2>Vimeo</h2><p><iframe class="auto-embed video vimeo" src="//player.vimeo.com/video/33219961" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></p><p><iframe class="auto-embed video vimeo" src="//player.vimeo.com/video/219048822" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></p><h2>Imgur</h2><p><img class="auto-embed image imgur" src="https://i.imgur.com/FY1AbSo.gif" alt="A Nice Image Embedded From imgur.com/" /></p><p><img class="auto-embed image imgur" src="https://i.imgur.com/uKnMvyp.jpg" alt="A Nice Image Embedded From imgur.com/" /></p><h3>Albums and Video Clips Don't Embed:</h3><p> <a href="https://i.imgur.com/d8skZVO.gifv">https://i.imgur.com/d8skZVO.gifv</a></p><p> <a href="https://imgur.com/a/hxsHXtQ">https://imgur.com/a/hxsHXtQ</a></p><p> <a href="https://imgur.com/a/hxsHXtQ">https://imgur.com/a/hxsHXtQ</a></p><h2>Gyazo</h2><p><img class="auto-embed image gyazo" src="https://i.gyazo.com/5593f3bbe109c38ebf07c16dd25dc4c4.gif" alt="A Nice Image Embedded From gyazo.com/" /></p><p><img class="auto-embed image gyazo" src="https://i.gyazo.com/40aa155043aa6d75a9a964c9df52fef5.jpg" alt="A Nice Image Embedded From gyazo.com/" /></p><h2>Other Links</h2><ul>\r\n â—€
\t<li> <a href="https://twitter.com/realdonaldtrump/status/257552283850653696">https://twitter.com/realdonaldtrump/status/257552283850653696</a></li>\r\n
\t<li> <a href="https://www.256kilobytes.com/">https://www.256kilobytes.com/</a></li>\r\n
\t<li> <a href="https://www.example.com/">https://www.example.com/</a></li>\r\n
</ul></h1>\n

Example Function Call

<?php
// The HTML string to be converted
$html_str = "<p>Hello. Here are some links:</p>"
          ."<ul><li>https://www.example.com/li></ul>"
          ."<p>https://vimeo.com/219048822</p>";

// Convert the plaintext links to videos and/or hyperlinks 
$html_str = all_urls_to_hyperlinks_or_embeds($html_str);

// Display the HTML
echo $html_str;

Code

PHP Code

<?php 
// The actual function to call.
// @param  String - $html_str - A string of arbitrary HTML
// @return String -           - A string of HTML with all plaintext links replaced with either video
//                              embeds (where possible) or hyperlinks (if links are not able to be embedded.
function all_urls_to_hyperlinks_or_embeds($html_str) {
        $chunks = preg_split('/(<.*>)/Ums', $html_str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
        $result = '';
        foreach ($chunks as $chunk) {
                if (substr($chunk,0,1) != '<')  
                        url_to_hyperlink_or_embed($chunk);  
                $result .= $chunk;
        } return $result;
}

// @param  String - &$plain_text_url - Passed by reference. 
// @return Bool   -                  - Returns False if the URL is invalid; returns TRUE otherwise. 
// Takes in a plaintext URL such as    https://www.example.com and,
// if the URL is from a domain that can be embedded, it is converted to that HTML markup
// If the URL cannot be embedded, it is converted to HTML for a hyperlink
function url_to_hyperlink_or_embed(&$plain_text_url) { 
        // Return FALSE if the string passed is not a valid URL 
        if (!filter_var($plain_text_url, FILTER_VALIDATE_URL)) 
                return FALSE;

        $original_plain_text_url = $plain_text_url;

        // bp = "base path; ep = "embed path"; 
        $platforms = [
                ['type'=>'iframe', 'css_classes' => 'youtube'    , 'bp' => "youtube.com\/watch\?v="  , 'ep' => 'www.youtube.com/embed/'          ],
                ['type'=>'iframe', 'css_classes' => 'vimeo'      , 'bp' => "vimeo.com\/"             , 'ep' => 'player.vimeo.com/video/'         ],
                ['type'=>'iframe', 'css_classes' => 'dailymotion', 'bp' => "dailymotion.com\/video\/", 'ep' => 'www.dailymotion.com/embed/video/'],
                ['type'=>'img'   , 'css_classes' => 'imgur'      , 'bp' => "imgur.com\/"             , 'ep' => 'i.imgur.com/'                    ],
                ['type'=>'img'   , 'css_classes' => 'gyazo'      , 'bp' => "gyazo.com\/"             , 'ep' => 'i.gyazo.com/'                    ],
        ]; 
        foreach ( $platforms as $p) { 
                if     ($p['type'] == 'iframe') plain_url_to_video_embed($plain_text_url, $p['bp'], $p['ep'],  $p['css_classes']); 
                elseif ($p['type'] == 'img'   ) plain_url_to_image_embed($plain_text_url, $p['bp'], $p['ep'],  $p['css_classes']); 
                
                // If the embed function matched the link and modified it, stop looping and return TRUE 
                if ( $plain_text_url !== $original_plain_text_url ) return TRUE;  
        }

        // If none of the embed functions worked, convert the URL to a regular hyperlink
        plain_url_to_hyperlink($plain_text_url);

        return TRUE;         
}
 
// Note: Since YT, Vimeo, DM, Imgur, and Gyazo are also links, this function is called last.  
function plain_url_to_hyperlink(&$chunk)     {
        $chunk = preg_replace('$(\s|^)(https?://[a-z0-9_./?=&#-~+:;]+)(?![^<>]*>)$i', ' <a href="$2">$2</a>'      , $chunk."");
        $chunk = preg_replace('$(\s|^)(www\.[a-z0-9_./?=&#-~+:;]+)(?![^<>]*>)$i'    , '<a href="http://$2">$2</a>', $chunk."");
}

// Note: The classes "auto-embed" and "video can be removed, if desired and if the accompanying
//       stylesheet is not being used. 
function plain_url_to_video_embed(&$chunk, $base_path, $embed_path, $css_classes) {
        $chunk = preg_replace(
                "/\s*[a-zA-Z\/\/:\.]*$base_path([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i",
                "<iframe class=\"auto-embed video $css_classes\" src=\"//$embed_path$1\" frameborder=\"0\" "
                ."webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>",
                $chunk);
}

// The file types that this matches (jpg, jpeg, png, gif, apng, and tiff) are from Imgur's help file here: 
// Note; Imgur also supports .mov and .mp4 files (video files). This regex does not include those file types
//    https://help.imgur.com/hc/en-us/articles/115000083326-What-files-can-I-upload-What-is-the-size-limit-
// Gyazo probably also support similar video file types (and might support other file types besides these;
// an offical doc listing all Gyazo file types couldn't be found when writing this code). 
// Note 2: The classes "auto-embed and image" can be removed, if desired. 
// FIXME - GIFV 
function plain_url_to_image_embed(&$chunk, $base_path, $embed_path, $css_classes) {
        $chunk = preg_replace(
                "/\s*[a-zA-Z\/\/:\.]*($base_path)([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)\.(jpg|jpeg|png|gif|apng|tiff)$/i",
                "<img class=\"auto-embed image $css_classes\" src=\"https://$embed_path$2.$4\" alt=\"A Nice Image Embedded From $1\" />",
                $chunk);
}

CSS

iframe.auto-embed {
        /* Center the Images */
        margin-left:auto; margin-right:auto; display:block;

        /* Give the Links a Mostly-Transparent Grey Background (Shows Before Resources Load) */
        background-color:rgba(219,219,219,0.2); 

        /* Give the Embeded Resources a Border (Or Put Other Arbitrary Styles Here) */
        box-sizing: border-box;
        border:     2px ridge gold;
}

/* Videos embedded from Vimeo have weird sizing that doesn't use the full iframe space. 
   Use a black 90% opaque background for these, instead of the light grey used for
   the others (since the BG is only visible while loading for everything except Vimeo. */
iframe.auto-embed.vimeo { background-color: rgba(0,0,0,0.9); }

/* Base dimensions for embeded video players, if not otherwise specified */
iframe.auto-embed.video { --player-width:  420px; --player-height: 315px; }

/* Use the aspect ratios suggested by YT, Vimeo, and DailyMotion 
   These are the default embed sizes that YT and DM use by default. 
   Vimeo's default size is 640px by 360px; since that is much larger
   than the others, scale it to 2/3rds of it's default size. */
iframe.auto-embed.video.youtube     { --player-width:  420px;           --player-height: 315px;           } 
iframe.auto-embed.video.vimeo       { --player-width:  calc(640px/1.5); --player-height: calc(360px/1.5); } 
iframe.auto-embed.video.dailymotion { --player-width:  480px;           --player-height: 270px;           } 

/* Make the player sizes responsive */
@media screen and (min-width:993px) {  iframe.auto-embed.video { width: var(--player-width);  height: var(--player-height); }  }
@media screen and (max-width:992px) {  iframe.auto-embed.video { width:90%; max-width:600px;  height: var(--player-height); }  }

In Conclusion

Here's some nice code. You can even use it, if that's something that you want to do. All code on this website is free to use for any purpose, including commercial purposes, with no requirement for attribution (i.e., do whatever the fuck you want).

Download more RAM. 🐏 ⨉ 0 Posted by August R. Garcia 6 months ago

Edit History

• [2019-02-10 22:12 PST] August R. Garcia (6 months ago)
• [2019-02-10 22:12 PST] August R. Garcia (6 months ago)
• [2019-02-10 22:12 PST] August R. Garcia (6 months ago)
• [2019-02-10 22:12 PST] August R. Garcia (6 months ago)
🕓 Posted at 10 February, 2019 22:12 PM PST

Profile Photo - August R. Garcia August R. Garcia LARPing as a Sysadmi... Portland, OR
🗎 177 🗨 891 🐏 264
Site Owner

Grahew Mattham

August Garcia is some guy who used to sell Viagra on the Internet. He made this website to LARP as a sysadmin while posting about garbage like user-agent spoofing, spintax, the only good keyboard, virtual assitants from Pakistan, links with the rel="nofollow" attributeproxiessin, the developer console, literally every link building method, and other junk.

Available at arg@256kilobytes.com, via Twitter, or arg.256kilobytes.com. Open to business inquiries based on availability.


Account created 8 months ago.
177 posts, 891 comments, and 264 RAMs.

Last active 4 hours ago:
Commented in thread Is XNXX safe for looking at filthy pornography?

Profile Photo - August R. Garcia August R. Garcia LARPing as a Sysadmi... Portland, OR
🗎 177 🗨 891 🐏 264
Site Owner

Footnote - This post is part of a work-in-progress for 256Kilobyte's patch 1.6.0. May update this post later with minor bug fixes / QOL updates to the code above.

Download more RAM. 🐏 ⨉ 0 Posted by August R. Garcia 6 months ago 🕓 Posted at 10 February, 2019 22:23 PM PST

Sir, I can do you a nice SEO.

Post a New Comment

To leave a comment, login to your account or create an account.

Do you like having a good time?

Read Quality Articles

Read some quality articles. If you can manage to not get banned for like five minutes, you can even post your own articles.

View Articles →

Argue with People on the Internet

Use your account to explain why people are wrong on the Internet forum.

View Forum →

Vandalize the Wiki

Or don't. I'm not your dad.

View Wiki →

Ask and/or Answer Questions

If someone asks a terrible question, post a LMGTFY link.

View Answers →

Make Some Money

Hire freelancers and/or advertise your goods and/or services. Hire people directly. We're not a middleman or your dad. Manage your own business transactions.

Register an Account
You can also login to an existing account or recover your password. All use of this site is subject to terms outlined in the terms of service and privacy policy.