Demo example based on Cipher API

Cipher API provides the algorithm dictionary which can be used for decrypting cipher codes.

Below is the demo example for the same which is also released in Github at https://github.com/bitnol/CipherAPI

<?php
/**
 * Author: Akhilesh Chandra Gupta
 * Author URI: http://www.bitnol.com
 * API URI: http://api.gitnol.com
 * Description: Demo of the application of Cipher API
 * License: MIT License
 */
	// Video with cipher signature 
	$video_id = "zDrNLZ1uJ2w";
	// get_video_info url formation
	// although for cipher signature we have to get the details from the video's webapge not from get_video_info object
	$info_url = "http://www.youtube.com/get_video_info?el=detailpage&asv=3&video_id=".$video_id;
	
	// youtube webpage url formation
	$yt_url = 'http://www.youtube.com/watch?v='.$video_id;
	// get the contents from the url
	$raw_data = file_get_contents($info_url);
	
	// parse the data received and save it as an array
	$output = array();
	parse_str($raw_data,$output);
	// check the status of the get_video_info object
	if($output['status']=='ok'){
		
		// check for the cipher signature
		$cipher = (isset($output['use_cipher_signature']) &&  $output['use_cipher_signature']=='True') ? true : false;
		// If cipher is true then we have to decode it
		if($cipher == true){
			
			// if cipher is true then we have to change the plan and get the details from the video's youtube wbe page
			$yt_html = file_get_contents($yt_url);
			
			// parse for the script containing the configuration
			preg_match('/ytplayer.config = {(.*?)};/',$yt_html,$match);
			$yt_object = @json_decode('{'.$match[1].'}') ;
			/// check if we are able to parse data
			if(!is_object($yt_object)){
				echo 'Sorry! Unable to parse Data';
			}else{
				
				// parse available formats
				$formats = $yt_object->args->url_encoded_fmt_stream_map;
				// get the player id from assets section
				$player_id = strbtwn($yt_object->assets->js,'html5player-','.js');
				$player_id = explode("/", $player_id);
				$player_id = $player_id[0];
				
				echo 'Player ID: '.$player_id.'<br /><hr />';
								
				// get the algo dictionary
				// first check if the file exists
				if(file_exists('./algo.json'))
					$algos = json_decode(file_get_contents('algo.json'),true);
				else{
					// API call to fetch the algo dictionary
					$algos_dict = file_get_contents("http://api.gitnol.com/getAlgo.php?playerID=".$player_id);
					
					// saving the algo dictonary in local env for easy access
					// Note: Developers should save the dictionary in their local env. 
					// Only make the API call for the new player ids which is not present in the algo dictionary.
					// Repeated violation will results in IP ban.
					file_put_contents('algo.json', $algos_dict);
					
					$algos = json_decode($algos_dict,true);
				}
				/// check if the algo exist for the given player id
				if(!array_key_exists($player_id, $algos)){
					
					// if the algo dictionary is old then fetch a new one
					$algos_dict = file_get_contents("http://api.gitnol.com/getAlgo.php?playerID=".$player_id);
					file_put_contents('algo.json', $algos_dict);
					
					$algos = json_decode($algos_dict,true);
					$algo = $algos[$player_id][1];
					 
				}else{
					$algo = $algos[$player_id][1];
				}
				
				echo 'Algo Used: '.$algo.'<br /><hr />';
							
				// download links formation
				$dlinks = array();
				$links  = explode(',',$formats);
				
				echo 'Download links <br /><br />';
				
				foreach ($links as $link) {
					parse_str($link,$linkarr);
					
					// parse link array one by one and decrypt the signature
					$dlinks[$linkarr['itag']] = $linkarr['url'] . "&signature=" . decrypt($linkarr['s'],$algo);
					echo $linkarr['itag'].'<br />';
					echo $dlinks[$linkarr['itag']].'<br /><br />';
				}
				echo '<hr />';
			}
		}else{
			echo 'Video Is not cipher not needed to decode';
		}
	}else{
		echo 'Unable to get Video Info';
	}
	
	// string helper function
	function strbtwn($content,$start,$end){
		$r = explode($start, $content);
		if (isset($r[1])){
			$r = explode($end, $r[1]);
			return $r[0];
		}
		return '';
	}
	
	// signature decoding 
	// parse the python string operation into php string operation
	function decrypt($sig, $algo){			
		$funcarr = explode(' + ', $algo);
		$decrypt = '';
		foreach($funcarr as $singfunc){
			$singfunc = substr($singfunc,2,-1);
			$operators = explode(':', $singfunc);
			if (sizeof($operators) == 1) {
				$decrypt .= $sig[$operators[0]];
			}
			if (sizeof($operators) == 2) {
				if($operators[0] == ''){
					$decrypt .= substr($sig, 0 ,$operators[1]);
				}
				if($operators[1] == ''){
					$decrypt .= substr($sig, $operators[0]);
				}
				if($operators[0] >= 0 && $operators[1] >= 0){
					$decrypt .= substr($sig, $operators[0], $operators[1] - $operators[0]);
				}
			}
			if (sizeof($operators) == 3) {
				if($operators[0] == '' && $operators[1] == ''){
					$decrypt .= strrev($sig);
				}
				if($operators[0] >=0 && $operators[1] == '' && $operators[0] != ''){
					$decrypt .= strrev(substr($sig, 0, $operators[0] + 1));
				}
				if($operators[0] >=0 && $operators[1] >= 0 && $operators[0] != '' && $operators[1] != ''){
					$decrypt .= strrev(substr($sig, $operators[1] + 1, $operators[0] - $operators[1]));
				}
			}
		}
		return $decrypt;
	}
?>

You can also fork it from Github. Please do leave feedback if any.

3 thoughts on “Demo example based on Cipher API”

  1. I guess youtube updated their youtube page code. and this regex cannot find html5player and stream urls. this code need to be updated

  2. Pingback: Homepage

Comments are closed.