Skip to content

Instantly share code, notes, and snippets.

@mi-ca
Last active November 12, 2021 03:36
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mi-ca/6d62789e99225139528215cc433fa437 to your computer and use it in GitHub Desktop.
Save mi-ca/6d62789e99225139528215cc433fa437 to your computer and use it in GitHub Desktop.
Bandcamp Embed - YouTube Embed & SoundCloud Embed : PHP Classes to auto embed and grab links from Bandcamp, Youtube and Soundcloud
<?php
/**
* Analyse a string , grab Bandcamp links and replace them by embed player
* You may change the html code of the player in buildEmbed method
*
* @author Michael CAILLET <a href="https://mi-ca.ch">mi-ca.ch</a>
* @version 1.0
* @uses $bc=new BandCampEmbed($string);
* echo $bc->getEmbededText();
* // OR
* var_dump( $bc->getLinks() );
*/
class BandCampEmbed{
private $str;
// urls found in the string
private $urls=array();
//regex for album -> https://regex101.com/r/t2gCG8/5
private $album_re = '/(https?:\/\/)?(?:www\.)?([a-z0-9\-]+?\.bandcamp\.com\/album\/[a-z0-9\-]+?\/?)(?:$|\s)/im';
//regex for track -> https://regex101.com/r/WEu4c5/6
private $track_re = '/(https?:\/\/)?(?:www\.)?([a-z0-9\-]+?\.bandcamp\.com\/track\/[a-z0-9\-]+?\/?)(?:$|\s)/im';
//regex for artist/label -> https://regex101.com/r/WEu4c5/7
private $artist_re = '/(https?:\/\/)?(?:www\.)?([a-z0-9\-]+?\.bandcamp\.com\/?)(?:releases)?(?:$|\s)/im';
// regex to grab the first album on artist page
private $firstAlbumArtistPage_re = '/<li data-item-id="(album)-([0-9]*)"/';
// regeg to get the id
private $bcId_re = '/EmbeddedPlayer\/v=[\d]\/(album|track)(?:=)([0-9]*)\//';
function __construct($str){
$this->str = $str; // store string
}
/**
* Check if string has bandcamp album link
* @param string $str the string to check
* @return array [provider][type][id][full_url][embed_src]
*/
public function has_albums($str=null){
$str=($str)?$str:$this->str;
$res=array();
preg_match_all($this->album_re, $str, $matches);
$i=0;
foreach ($matches[2] as $album) {
$res[]=$this->urls[]=$this->getRemoteAlbumID($album,$matches[1][$i]);
$i++;
}
return $res;
}
/**
* Check if string has bandcamp track link
* @param string $str the string to check
* @return array [provider][type][id][full_url][embed_src]
*/
public function has_track($str=null){
$str=($str)?$str:$this->str;
$res=array();
preg_match_all($this->track_re, $str, $matches);
$i=0;
foreach ($matches[2] as $track) {
$res[]=$this->urls[]=$this->getRemoteAlbumID($track,$matches[1][$i]);
$i++;
}
return $res;
}
/**
* Check if string has artist link and grab the first album
* @param string $str the string to check
* @return array [provider][type][id][full_url][embed_src]
*/
public function has_artist($str=null){
$str=($str)?$str:$this->str;
$res=array();
preg_match_all($this->artist_re, $str, $matches);
if($matches[0]){
$i=0;
foreach ($matches[2] as $artist) {
$bcPage=$this->downloadPage($artist);
preg_match($this->bcId_re, $bcPage, $ids);
if(!$ids){
preg_match($this->firstAlbumArtistPage_re, $bcPage, $ids);
}
if($ids){
$res[]= $this->urls[]= array('provider'=>'bandcamp','type'=>$ids[1],'id'=>$ids[2],'full_url'=>$matches[1][$i].$artist,'url'=>$artist,'embed_src'=>'https://bandcamp.com/EmbeddedPlayer/'.$ids[1].'='.$ids[2]);
}
$i++;
}
}
return $res;
}
<?php
/**
* Analyse a string , grab SoundCloud links and replace them by embed player
* You may change the html code of the player in buildEmbed method
*
* @author Michael CAILLET <a href="https://mi-ca.ch">mi-ca.ch</a>
* @version 1.0
* @uses $sc=new SoundCloudEmbed($string);
* echo $sc->getEmbededText();
* // OR
* var_dump( $sc->getLinks() );
*/
class SoundCloudEmbed{
private $str;
private $urls=array();
// https://regex101.com/r/3jgPki/3
private $sc_re = '/((https?:\/\/)?(?:www\.)?(soundcloud\.com\/\S+|snd\.sc\/\S+))/i';
private $scID_re = '/(?:url=)(https%3A%2F%2Fapi.soundcloud.com%2F(tracks|playlists|users)%2F(\d*))/';
function __construct($str){
$this->str=$str;
}
/**
* Check if string has soundcloud links
* @param string $str the string to check
* @return array [provider][type][id][full_url][embed_src]
*/
public function has_soundCloud($str=null){
$str=($str)?$str:$this->str;
$res=array();
preg_match_all($this->sc_re, $str, $matches);
if($matches[0]){
$i=0;
foreach ($matches[0] as $url) {
$matches[2][$i]=(empty($matches[2][$i]))?'https://':$matches[2][$i];
$oembedUrl='soundcloud.com/oembed?format=json&url='.$matches[2][$i].$matches[3][$i];
$response=json_decode($this->downloadPage($oembedUrl));
if($response){
preg_match($this->scID_re,$response->html,$r);
if($r[0] && $r[2] && $r[3]){
$res[]=$this->urls[] = array('provider'=>'soundcloud',
'type'=>$r[2],
'id'=>$r[3],
'embed_src'=>'https://w.soundcloud.com/player/?visual=true&amp;'.$r[0].'&amp;show_artwork=true',
'full_url'=>$url
);
}
}
$i++;
}
}
return $res;
}
/**
* return the string with soundcloud embeded players
* @return string replace all sc urls with players
*/
public function getEmbededText(){
$str=$this->str;
if(empty($this->urls)){
$this->has_soundCloud();
}
foreach ($this->urls as $sc) {
//$url = preg_replace('([\.]|[(\?)])', '\\$1', $sc['full_url']);
$str = preg_replace('@'.str_replace('?', '\?',str_replace('.', '\.',$sc['full_url'])).'@',$this->buildEmbed($sc) , $str);
}
return $str;
}
/**
* get All youtube url in a string
* @return array [provider][type][id][full_url][embed_src]
*/
public function getLinks(){
if(empty($this->urls)){
$this->has_soundCloud();
}
return $this->urls;
}
/**
* Use cURL to getPageContent
* @param string $url url to open
* @return string html of the page
*/
private function downloadPage($url){
//The cURL stuff...
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, 'https://'.$url);
curl_setopt($ch, CURLOPT_VERBOSE, true);
$agent= 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36';
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$bcPage = curl_exec($ch);
curl_close($ch);
return $bcPage;
}
/**
* Create the embed html
* @param array $id [provider][type][id][full_url][embed_src]
* @return string embed html
*/
private function buildEmbed($id){
if($id){
// <iframe width="100%" height="300" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/playlists/104662358&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;visual=true"></iframe>
return '<div class="scPlayer"><iframe width="100%" height="300" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/'.$id['type'].'/'.$id['id'].'&amp;buying=false&amp;sharing=false&amp;show_playcount=false&amp;show_bpm=false&amp;auto_play=false&amp;hide_related=false&amp;show_comments=false&amp;show_user=false&amp;show_reposts=false&amp;visual=true"></iframe></div>';
}
return false;
}
}
<?php
/**
* Analyse a string , grab Youtube links and replace them by embed player
* You may change the html code of the player in buildEmbed method
*
* @author Michael CAILLET <a href="https://mi-ca.ch">mi-ca.ch</a>
* @version 1.0
* @uses $yt=new YoutubeEmbed($string);
* echo $yt->getEmbededText();
* // OR
* var_dump( $yt->getLinks() );
*/
class YoutubeEmbed{
private $str;
// the urls found in the string
private $urls=array();
//https://regex101.com/r/xQ7a0y/1
private $youtube_re ='/(?:https?:)?(?:\/\/)?(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube(?:-nocookie)?\.com\S*?[^\w\s-])([\w-]{11})(?=[^\w-]|$)(?![?=&+%\w.-]*(?:[\'"][^<>]*>|<\/a>))[?=&+%\w.-]*/im';
function __construct($str){
$this->str = $str;
}
/**
* Check if string has youtube links
* @param string $str the string to check
* @return array [provider][type][id][full_url][embed_src]
*/
public function has_youtube($str=null){
$str=($str)?$str:$this->str;
$res=array();
preg_match_all($this->youtube_re, $str, $matches);
$i=0;
foreach ($matches[0] as $yt) {
$res[]= $this->urls[] = array('provider'=>'youtube','type'=>'youtube','id'=>$matches[1][$i],'url'=>$yt,'full_url'=>$yt,'embed_src'=>'https://www.youtube-nocookie.com/embed/'.$matches[1][$i]);
$i++;
}
return $res;
}
/**
* get All youtube url in a string
* @return array [provider][type][id][full_url][embed_src]
*/
public function getLinks(){
if(empty($this->urls)){
$this->has_youtube();
}
return $this->urls;
}
/**
* return the string with youtube embeded players
* @return string replace all bc urls with players
*/
public function getEmbededText(){
$str=$this->str;
$str = preg_replace($this->youtube_re,$this->buildEmbed('$1') , $str);
return $str;
}
/**
* Create the embed html
* @param array $id [provider][type][id][full_url][embed_src]
* @return string embed html
*/
private function buildEmbed($id){
if($id){
return '<div class="ytPlayer"><iframe width="640" height="360" src="https://www.youtube-nocookie.com/embed/'.$id.'?rel=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe></div>';
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment