How do I get a random YouTube video with the YouTube API?
I know it's a little bit off-topic but I can offer the following bash script. I use it on my Raspberry Pi and it works quite well.
#!/bin/sh
while [ true ];
do
searchresult=""
while [ -z "$searchresult" ]; do
rand=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-5};echo)
echo "$rand"
searchresult=$(googler -C -n 100 --np -x -w https://www.youtube.com "$rand")
done
urls=$(echo "$searchresult" | grep -o "https://www.youtube.com/watch?v=...........")
url=$(shuf -e -n 1 $urls)
echo "$url"
omxplayer -o hdmi $(youtube-dl -f mp4 -g "$url")
done
Prerequisites are that you have installed googler and youtube-dl. My initial idea was to generate random 11 character strings and to append them to the base URL for YouTube videos. However, the number of possible permutations is enormous (26 capital letters + 26 small letters + 10 digits + hyphen + underscore = 64 characters; 64^11=7.38x10^19 permutations) and will be used up if every person on the Earth uploads 10 billion videos. That's why randomly generating the complete 11-character identifier is not a practicable approach. My script generates random 5-character strings instead (variable "rand") and passes them as a search query to googler. Googler searches the YouTube site for these random strings and in most cases it returns results (variable "searchresult"). In case there is no result, the search is repeated with another random string and so on till success. Usually it takes one to three tries. I tried with different lengths of the search string - 4 is maybe not unique enough and 6 is too long and it can take a lot of tries to get a result and I observed that if the script sends more than 10 search requests in short time, Google temporarily blocks me from further searches.
In the next step, the script extracts the hyperlinks to the YouTube videos from the search results and puts them in the variable "urls". Then one of them is randomly selected to be played (variable "url") and passed to the player - omxplayer in my case, but you can replace it with whichever player you want. Omxplayer is nice on the Raspberry Pi because it uses the hardware acceleration and outputs via hdmi directly to my TV set. If I change "-o hdmi" to "-o local" the audio is sent via the 3.5 mm stereo jack to an external amplifier. Pressing "q" during play stops playing the current video and the next random one starts automatically. It will go on forever till you press Ctrl-C to stop the script.
Additional tips
With some modifications you can get random videos on a given topic. For example, if we put "Deep Purple" as an additional search term we'll get random music videos by Deep Purple:
#!/bin/sh
while [ true ];
do
searchresult=""
while [ -z "$searchresult" ]; do
rand=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-2};echo)
echo "$rand"
searchresult=$(googler -C -n 10 --np -x -w https://www.youtube.com "$rand" "Deep Purple")
done
urls=$(echo "$searchresult" | grep -o "https://www.youtube.com/watch?v=...........")
url=$(shuf -e -n 1 $urls)
echo "$url"
omxplayer -o hdmi $(youtube-dl -f mp4 -g "$url")
done
Note that in the last example I have reduced the randomness factor to a 2-character string because it will be difficult to find a match for a 5-character string in the relatively small subset of all YouTube videos that contain the search term "Deep Purple". Also here I have limited the number of returned search results by googler to 10 to keep them relevant. With 100 I would also get less relevant results like videos of amateurs trying to play songs by Deep Purple.
The next script will play randomly only new videos that have been uploaded within the last 12 hours:
#!/bin/sh
while [ true ];
do
searchresult=$(googler -C -n 100 --np -t h12 -x -w https://www.youtube.com "")
urls=$(echo "$searchresult" | grep -o "https://www.youtube.com/watch?v=...........")
url=$(shuf -e -n 1 $urls)
echo "$url"
omxplayer -o hdmi $(youtube-dl -f mp4 -g "$url")
done
You can set different time constraints. See the documentation of googler for more details.
Step 1: Create API-Key
- Create a google-Account
- Visit: https://console.developers.google.com/
- Create a new project: Click on Create new Project in head-menu and give it a name
- Now Activate the YoutTubeData API: Click it and enable it.
- Insert your Applications-Infos
- Click "create Credentials"
- Klick what do i need?
- Note your API-Key
Now you can access the YouTube-API.
Step 2: Use YouTube-API to crawl Videos
In this step we use the YouTube-API to get random VideoId's. With the following Code-Samples you will get 50 random Apis from the YouTube-Search. That's the maximum. You can store them in a DB or return a random ID directly.
Attention: There is a limit of 30,000 units/second/user and 1,000,000 per day.
Codesamples
[C#-Example]
using System;
using System.Linq;
using System.Net;
using Newtonsoft.Json;
namespace YouTube
{
class Program
{
private static Random random = new Random();
public static string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
static void Main(string[] args)
{
var count = 50;
var API_KEY = "YOUR KEY";
var q = RandomString(3);
var url = "https://www.googleapis.com/youtube/v3/search?key=" + API_KEY + "&maxResults="+count+"&part=snippet&type=video&q=" +q;
using (WebClient wc = new WebClient())
{
var json = wc.DownloadString(url);
dynamic jsonObject = JsonConvert.DeserializeObject(json);
foreach (var line in jsonObject["items"])
{
Console.WriteLine(line["id"]["videoId"]);
/*store your id*/
}
Console.Read();
}
}
}
}
[PHP-Example]
function crawlVideos($count = 50)
{
$q = $this->generateRandomString(3);
$url = "https://www.googleapis.com/youtube/v3/search?key=" . self::API_KEY . "&maxResults=$count&part=snippet&type=video&q=" . $q;
$JSON = file_get_contents($url);
$JSON_Data_search = json_decode($JSON);
foreach ($JSON_Data_search->{"items"} as $result) {
$videoId = ($result->{"id"}->{"videoId"});
/*Insert video to your database*/
}
}
function generateRandomString($length = 10)
{
return substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length / strlen($x)))), 1, $length);
}
[Python-Example]
import json
import urllib.request
import string
import random
count = 50
API_KEY = 'your_key'
random = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(3))
urlData = "https://www.googleapis.com/youtube/v3/search?key={}&maxResults={}&part=snippet&type=video&q={}".format(API_KEY,count,random)
webURL = urllib.request.urlopen(urlData)
data = webURL.read()
encoding = webURL.info().get_content_charset('utf-8')
results = json.loads(data.decode(encoding))
for data in results['items']:
videoId = (data['id']['videoId'])
print(videoId)
#store your ids
Step 3: Generate/Return your Video-URL
Now read a random ID from database like:
SELECT 'id'
FROM yttable
WHERE 1 ORDER BY RAND() LIMIT 1
Your random video is:
https://www.youtube.com/embed/[random ID]
Have fun!
There appears to be no way to do this, however there are ways to approximate what you're looking for. See here for ideas.
The basic ideas from those pages are to use the most recent uploads feed (if you don't care about when something was uploaded) or simply get a dump of ALL youtube videos and randomly select a URL from those.
To quote the youtube API guy in first link:
As others have mentioned, we make any data dumps or the like available. All your interaction with YouTube needs to be done via the standard API.
I can't say that I have enough of a background in statistics to suggest how you could retrieve a truly random sample of videos. I do think that going about it by attempting to generate 11 character YouTube video ids is probably the wrong approach, though—there are just too many non-existent video ids that you'll bump up against, and I don't think the best use of the API is to make requests that will return HTTP 404 responses X% of the time.
You might have better luck just using the API to search for words or phrases that are picked at "random" and taking a sampling of the results. If you do that, you should think about what value to use for the orderby= URL parameter. The default ordering is "relevance", which will lead to the top results being the ones that our algorithms think are the most relevant to your search terms. This might skew your results if you always grab the first entry or the like. You could also order by "published" which will give you a reverse-chronological feed of videos.
Cheers, -Jeff Posnick, YouTube API Team as With regards to randomyoutubevideo.net, this is what the "About" page of that site has to say:
So how can we provide truly random links to YouTube videos? It turns out that the YouTube programming interface (API) provides additional functions that allow the discovery of videos that are much more random. Using a number of tricks, combined with a little manipulation of the space-time frabric, we have managed to create a process that yiields truly random links to YouTube videos.
The random YouTube function on this page currently uses a subset of the database. Over time we will expand this database and, depending on demand, may make it available free of charge via an API.
I understand this to mean that they have been pulling large lists of videos from the API and making a DB of them from which they randomly select.
Is a dirty crawler an option?
Because I've used a simple random youtube vid link generator. It was only for accumulating a big db of videos, not for production.
It seems to be (very) similar to "youtuberandomvideo.com" approach as he described.
import re, urllib
from random import randint
def random_str(str_size):
res = ""
for i in xrange(str_size):
x = randint(0,25)
c = chr(ord('a')+x)
res += c
return res
def find_watch(text,pos):
start = text.find("watch?v=",pos)
if (start<0):
return None,None
end = text.find(" ",start)
if (end<0):
return None,None
if (end-start > 200): #silly heuristics, probably not a must
return None,None
return text[start:end-1], start
def find_instance_links():
base_url = 'https://www.youtube.com/results?search_query='
url = base_url+random_str(3)
#print url
r = urllib.urlopen(url).read()
links = {}
pos = 0
while True:
link,pos = find_watch(r,pos)
if link == None or pos == None:
break
pos += 1
#print link
if (";" in link):
continue
links[link] = 1
items_list = links.items()
list_size = len(items_list)
selected = randint(list_size/2,list_size-1)
return items_list[selected][0]
for i in xrange(1000):
link = find_instance_links()
print link
As you can see it's fairly simplistic and could probably break easily, but IIRC I managed to quickly get thousands of random video links which was all that I needed, and it's only few lines of code...
Some explanation of the code: (random->pseudo random ...)
1. Random generation of search queries (3 letters long here)
2. Randomly selecting some link from the bottom half of the video links (the motivation was to avoid commercials)
Note:The code is messy - it should only serve as a basic example of the technique, not of proper code design and/or elegant python code.