The Wayback Machine - https://web.archive.org/web/20130622031416/http://aaronparecki.com:80/articles/2013/05/09/1/experimenting-with-auto-embedding-content

Experimenting with auto-embedding content

As part of expanding the functionality of the software my site runs on, I thought it was about time to start showing inline content when I post links in notes.

You are probably already familiar with this idea from Twitter's implementation of "Twitter Cards" as well as how Facebook displays content inline in the News Feed.

For my own site, I wanted to auto-embed more than just photos and video, so I went and found content I had linked to in the past and wrote some simple pattern matchers to look for those links. Below are the various types of content I am now providing inline previews for! I've also provided the source code I used to find the URLs as well as how I translate that to the appopriate embed code.

My notes contain only plain text and a URL, and p3k will auto-detect any URLs it knows about and render the appropriate embed code for the media. I chose to put the embedded media below the entier post content to keep the flow of the "plaintext" note.

My next step is to parse arbitrary URLs looking for an h-entry, and display a mini preview of the content linked to.

Gist

Gist

Code

if(preg_match_all('/gist\.github\.com\/([^\/]+\/[0-9a-f]+)/i', $this->body, $matches)) {
  foreach($matches[1] as $m)
    $embedded[] = '<script src="https://gist.github.com/' . $m . '.js"></script>';
}

SoundCloud

SoundCloud

Code

SoundCloud provides an oEmbed endpoint that needs to be queried to retrieve the HTML embed code, since there is a secret token in addition to the URL

if(preg_match_all('/https?:\/\/soundcloud\.com\/([^\/]+)\/([^\/ ]+)/', $this->body, $matches)) {
  foreach($matches[0] as $m) {
    // Fetch the embed code via the Soundcloud oEmbed endpoint
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'http://soundcloud.com/oembed?format=json&url=' . urlencode($m));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    $data = json_decode($response);
    $embedded[] = $data->html;
  }
}

SlideShare

SlideShare

Code

if(preg_match_all('/slideshare\.net\/[^\/]+\/[^ ]+-([0-9]+)/', $this->body, $matches)) {
  foreach($matches[1] as $m)
    $embedded[] = '<iframe src="http://www.slideshare.net/slideshow/embed_code/' . $m . '" width="600" height="440" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>';
}

Spincam

Spincam

Code

if(preg_match_all('/spincam\.net\/s\/([a-z0-9]+)/i', $this->body, $matches)) {
  foreach($matches[1] as $m)
    $embedded[] = '<div style="width: 360px; margin: 0 auto;"><iframe src="http://spincam.net/embed/' . $m . '" style="width:360px; height:480px; background:none; border:none; text-align:center;" scrolling="no"></iframe></div>';
}

Google Maps

Google Maps

Code

if(preg_match_all('/http:\/\/goo\.gl\/maps\/[a-z0-9]+/i', $this->body, $matches)) {
  foreach($matches[0] as $m) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $m);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_exec($ch);
    $mapURL = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);

    $embedded[] = '<iframe width="600" height="420" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="' . $mapURL . '&amp;source=embed&amp;output=svembed"></iframe>';
  }
}

Images

Images

Code

if(preg_match_all('/https?:\/\/([^\s]+\.[^\s\.]+\.(png|jpg|jpeg|gif))/i', $this->body, $matches)) {
  foreach($matches[0] as $m)
    $embedded[] = '<img src="' . $m . '" />';
}

Video

Video

Code

if(preg_match_all('/(https?:\/\/)([^\s]+\.[^\s\.]+\.(mp4))/i', $this->body, $matches)) {
  foreach($matches[0] as $i=>$m)
    $embedded[] = '<div style="width: 480px; margin: 0 auto;"><video autoplay controls width="480"><source src="' . $m . '" type="video/mp4" /><a href="' . $m . '"><span class="protocol">' . $matches[1][$i] . '</span>' . $matches[2][$i] . '</a></video></div>';
}

YouTube

YouTube

Code

if(preg_match_all('/(youtube\.com|youtu\.be)\/watch\?v=([a-z0-9]+)/i', $this->body, $matches)) {
  foreach($matches[2] as $m)
    $embedded[] = '<div style="width: 600px; margin: 0 auto;"><iframe class="youtube-player auto-link figure" width="600" height="420" style="border:0"  src="http://www.youtube.com/embed/' . $m . '"></iframe></div>';
}

Vimeo

Vimeo

Code

if(preg_match_all('/vimeo\.com\/([0-9]+)/', $this->body, $matches)) {
  foreach($matches[1] as $m)
    $embedded[] = '<div style="width: 600px; margin: 0 auto;"><iframe src="http://player.vimeo.com/video/' . $m . '" width="600" height="400" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></div>';
}

Vine

Vine

Code

if(preg_match_all('/vine\.co\/v\/([a-z0-9]+)/i', $this->body, $matches)) {
  foreach($matches[1] as $m) 
    $embedded[] = '<div style="width: 480px; margin: 0 auto;"><iframe class="vine-embed" src="https://vine.co/v/' . $m . '/embed/simple" width="480" height="480" frameborder="0"></iframe></div>';
  // Add the necessary footer scripts to activate the embedded content
  $footerScripts[] = '<script async src="//platform.vine.co/static/scripts/embed.js" charset="utf-8"></script>';
}