I'm inserting videos on youtube using API in PHP version. But I'm not able to include a highlight comment in the videos. In the youtube documentation the example is in json , and as I'm doing it in php it just doesn't work.
See part of my code is like this:
// Create a snippet with title, description, tags and category ID
// Create an asset resource and set its snippet metadata and type.
// This example sets the video's title, description, keyword tags, and
// video category.
$snippet = new Google_Service_YouTube_VideoSnippet();
$snippet->setTitle("Cats are cute #".$filme['Data ID']);
$snippet->setDescription($filme['titulo']);
$snippet->setTags('cats','cutecats','cute');
// Numeric video category. See
// https://developers.google.com/youtube/v3/docs/videoCategories/list
$snippet->setCategoryId("19");
// Set the video's status to "public". Valid statuses are "public",
// "private" and "unlisted".
$status = new Google_Service_YouTube_VideoStatus();
$status->privacyStatus = "public";
// Associate the snippet and status objects with a new video resource.
$video = new Google_Service_YouTube_Video();
$video->setSnippet($snippet);
$video->setStatus($status);
And the youtube suggestion to include comments using the API is this:
{
"snippet": {
"channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
"topLevelComment": {
"snippet": {
"textOriginal": "This video is awesome!"
}
},
"videoId": "MILSirUni5E"
}
}
I tried like this and it didn't work:
$snippet->textOriginal('My comment');
How can I submit a featured comment using youtube API in php?
Related
I have a page where users can paste a Youtube video url and then I need to extract the video's ID in order to get the video's thumbnail image. The hard part is to get a reliable way of extracting the video ID from the video url. There are a number of regex solutions here but for me none of these are 100% reliable. Here's a few:
JavaScript REGEX: How do I get the YouTube video id from a URL?
Youtube API - Extract video ID
It's like a contest of who has a longer regex. I feel like the right way would be to get this information from Youtube's api, but looking at it, seems like this option is not available:
https://developers.google.com/apis-explorer/#p/youtube/v3/
As you can see everything is based on the video id. I find it ridiculous that I need the actual video ID to get any information about the video since no real world user will ever even know what the video id is. Vimeo has this feature built into their API. Here is an example:
https://vimeo.com/api/oembed.json?url=https://vimeo.com/29474908
Does anyone have a solution for this that does not involve some regular expression?
Doing a search with the API works with different YouTube URL types. The URL is passed as the query term q.
https://www.googleapis.com/youtube/v3/search/?key=<YOUR_KEY>&part=snippet&q=youtu.be/M7lc1UVf-VE
Maybe some case could result in more than one item, but the normal search result is just one match:
{
kind: "youtube#searchListResponse",
etag: ""m2yskBQFythfE4irbTIeOgYYfBU/j2Px-5q--mgJEsrfjg4L0Mgn_L8"",
regionCode: "ES",
pageInfo: {
totalResults: 1,
resultsPerPage: 5
},
items: [
{
kind: "youtube#searchResult",
etag: ""m2yskBQFythfE4irbTIeOgYYfBU/_1gFVi_i_djlS4OZWPGtcZ3iSLQ"",
id: {
kind: "youtube#video",
videoId: "M7lc1UVf-VE"
},
snippet: {
publishedAt: "2013-04-10T17:25:04.000Z",
channelId: "UC_x5XG1OV2P6uZZ5FSM9Ttw",
title: "YouTube Developers Live: Embedded Web Player Customization",
description: "On this week's show, Jeff Posnick covers everything you need to know about using player parameters to customize the YouTube iframe-embedded player.",
thumbnails: {
default: {
url: "https://i.ytimg.com/vi/M7lc1UVf-VE/default.jpg",
width: 120,
height: 90
},
medium: {
url: "https://i.ytimg.com/vi/M7lc1UVf-VE/mqdefault.jpg",
width: 320,
height: 180
},
high: {
url: "https://i.ytimg.com/vi/M7lc1UVf-VE/hqdefault.jpg",
width: 480,
height: 360
}
},
channelTitle: "Google Developers",
liveBroadcastContent: "none"
}
}
]
}
I tested with some of the URL variations from this answer and most worked:
var urls = [
'//www.youtube-nocookie.com/embed/M7lc1UVf-VE?rel=0',
'https://www.youtube.com/watch?v=M7lc1UVf-VE&feature=channel',
'https://www.youtube.com/watch?v=M7lc1UVf-VE&playnext_from=TL&videos=osPknwzXEas&feature=sub',
'https://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I', // <---- invalid
'https://youtu.be/M7lc1UVf-VE',
'https://www.youtube.com/watch?v=M7lc1UVf-VE&feature=youtu.be',
'https://youtu.be/M7lc1UVf-VE',
'https://www.youtube.com/watch?v=M7lc1UVf-VE&feature=channel',
'https://www.youtube.com/watch?v=M7lc1UVf-VE&playnext_from=TL&videos=osPknwzXEas&feature=sub',
'https://www.youtube.com/ytscreeningroom?v=M7lc1UVf-VE', // <---- invalid
'https://www.youtube.com/embed/M7lc1UVf-VE?rel=0',
'https://www.youtube.com/watch?v=M7lc1UVf-VE',
'https://youtube.com/v/M7lc1UVf-VE?feature=youtube_gdata_player',
'https://youtube.com/vi/M7lc1UVf-VE?feature=youtube_gdata_player', // <---- invalid
'https://youtube.com/?v=M7lc1UVf-VE&feature=youtube_gdata_player',
'https://www.youtube.com/watch?v=M7lc1UVf-VE&feature=youtube_gdata_player',
'https://youtube.com/?vi=M7lc1UVf-VE&feature=youtube_gdata_player', // <---- invalid
'https://youtube.com/watch?v=M7lc1UVf-VE&feature=youtube_gdata_player',
'https://youtube.com/watch?vi=M7lc1UVf-VE&feature=youtube_gdata_player',
'https://youtu.be/M7lc1UVf-VE?feature=youtube_gdata_player'
];
var my_key = '<YOUR_KEY>';
function getUri(uri){
$.get('https://www.googleapis.com/youtube/v3/search/?key='+my_key+'&part=snippet&q='+uri, function(data) {
if(data.items.length !== 0)
console.log(data.items[0].snippet.publishedAt);
else
console.warn('no items for',uri)
});
}
for (i = 0; i < urls.length; ++i) {
getUri(urls[i]);
}
I would like to fetch details of a YouTube channel which has a custom URL, like https://www.youtube.com/c/pratiksinhchudasamaisawesome.
Custom channel URLs follow this format: https://www.youtube.com/c/{custom_channel_name}.
I can fetch the details of YouTube channels by Channel ID and username without any issues. Unfortunately, I need to use the custom channel URL which is the only time I encounter this issue.
I developed my app few months ago, and the custom channel URL was working up until a few days ago. Now, the YouTube data API does not return anything for the YouTube custom channel URL if I try get details using their custom name.
To get the details of this channel: https://www.youtube.com/user/thenewboston, for example, the request would be:
GET https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername=thenewboston&key={YOUR_API_KEY}
Response
200
- SHOW HEADERS -
{
"kind": "youtube#channelListResponse",
"etag": "\"zekp1FB4kTkkM-rWc1qIAAt-BWc/8Dz6-vPu69KX3yZxVCT3-M9YWQA\"",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#channel",
"etag": "\"zekp1FB4kTkkM-rWc1qIAAt-BWc/KlQLDlUPRAmACwKt9V8V2yrOfEg\"",
"id": "UCJbPGzawDH1njbqV-D5HqKw",
"snippet": {
"title": "thenewboston",
"description": "Tons of sweet computer related tutorials and some other awesome videos too!",
"publishedAt": "2008-02-04T16:09:31.000Z",
"thumbnails": {
"default": {
"url": "https://yt3.ggpht.com/--n5ELY2uT-U/AAAAAAAAAAI/AAAAAAAAAAA/d9JvaIEpstw/s88-c-k-no-rj-c0xffffff/photo.jpg"
},
"medium": {
"url": "https://yt3.ggpht.com/--n5ELY2uT-U/AAAAAAAAAAI/AAAAAAAAAAA/d9JvaIEpstw/s240-c-k-no-rj-c0xffffff/photo.jpg"
},
"high": {
"url": "https://yt3.ggpht.com/--n5ELY2uT-U/AAAAAAAAAAI/AAAAAAAAAAA/d9JvaIEpstw/s240-c-k-no-rj-c0xffffff/photo.jpg"
}
},
"localized": {
"title": "thenewboston",
"description": "Tons of sweet computer related tutorials and some other awesome videos too!"
}
}
}
]
}
It works perfectly.
Now we have to get details of these channels:
https://www.youtube.com/c/eretteretlenek
https://www.youtube.com/c/annacavalli
Then we get:
GET https://www.googleapis.com/youtube/v3/channels?part=snippet&forUsername=annacavalli&key={YOUR_API_KEY}
Response
200
- SHOW HEADERS -
{
"kind": "youtube#channelListResponse",
"etag": "\"zekp1FB4kTkkM-rWc1qIAAt-BWc/TAiG4jjJ-NTZu7gPKn7WGmuaZb8\"",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 5
},
"items": [
]
}
This can be easily reproduced using the API explorer.
Simplest solution, using API only, is to just use Search:list method of YouTube Data API. From what I can tell (mind you, this is from my own research, official docs say nothing on this subject!), if you search using the custom URL component, with "channel" result type filter and "relevance" (default) sorting, first result should be what you're looking for.
So the following query gets 16 results, with the first one being the one you're looking for. Same goes for all other custom channel URLs I tested, so I think this is the most reliable way of doing this.
GET https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&q=annacavalli&type=channel&key={YOUR_API_KEY}
The other idea is just scraping YouTube page at the custom URL, where you can find ChannelID in one of the meta tags in HTML code. But that's ineffective, unreliable and AFAIK in violation of YouTube terms of use.
Edit: Well, it returns no results for smaller channels, so it's not reliable at all.
Workaround
Expanding off of #jkondratowicz answer, using the search.list in combination with channels.list you can most of the time resolve the channel from the custom url value.
The channel resource has a property customUrl so if we take the channels from the search.list results and get that extra detail about them from the channels.list it is possible to try and match up the custom url value with the customUrl property.
A working JavaScript method here, just replace the api key with your own. Though it is still not perfect, this tries the first 50 channels returned. More could be done with paging and pageTokens.
function getChannel(customValue, callback) {
const API_KEY = "your_api_key"
$.ajax({
dataType: "json",
type: "GET",
url: "https://www.googleapis.com/youtube/v3/search",
data: {
key: API_KEY,
part: "snippet",
q: customValue,
maxResults: 50,
order: 'relevance',
type: 'channel'
}
}).done(function (res) {
const channelIds = [];
for (let i=0; i<res.items.length; i++) {
channelIds.push(res.items[i].id.channelId);
}
$.ajax({
dataType: "json",
type: "GET",
url: "https://www.googleapis.com/youtube/v3/channels",
data: {
key: API_KEY,
part: "snippet",
id: channelIds.join(","),
maxResults: 50
}
}).done(function (res) {
if (res.items) {
for (let i=0; i<res.items.length; i++) {
const item = res.items[i];
if (item.snippet.hasOwnProperty("customUrl") && customValue.toLowerCase() === item.snippet.customUrl.toLowerCase()) {
callback(item);
}
}
}
}).fail(function (err) {
logger.err(err);
});
}).fail(function (err) {
logger.err(err);
});
}
A good example using it with https://www.youtube.com/c/creatoracademy.
getChannel('creatoracademy', function (channel) {
console.log(channel);
});
However, it is still unreliable as it depends on if the channel comes back in the original search.list query. It seems possible that if the custom channel url is too generic that the actual channel may not come back in the search.list results. Though this method is much more reliable then depending on the first entry of search.list to be the right one as search results don't always come back in the same order.
Issue
There has been at least three feature requests to Google in the past year requesting for an additional parameter for this custom url value but they were all denied as being infeasible. Apparently it is too difficult to implement. It was also mentioned as not being on their roadmap.
https://issuetracker.google.com/issues/174903934 (Dec 2020)
https://issuetracker.google.com/issues/165676622 (Aug 2020)
https://issuetracker.google.com/issues/161718177 (Jul 2020)
Resources
Google: Understand your channel URLs
Search: list | YouTube Data API
Channels: list | YouTube Data API
An alternative way is to use a parser (PHP Simple HTLM DOM parser, for the example below : PHP Simple HTML DOM Parser) :
<?php
$media_url = 'https://www.youtube.com/c/[Channel name]';
$dom = new simple_html_dom();
$html = $dom->load(curl_get($media_url));
if (null !== ($html->find('meta[itemprop=channelId]',0))) {
$channelId = $html->find('meta[itemprop=channelId]',0)->content;
}
?>
(Using Youtube api's "search" method has a quota cost of 100)
It is possible the get the channel ID by the video ID, that can help depends on the need fo your application.
Here are an example:
$queryParams = [
'id' => 'UcDjWCEvZLM'
];
$response = $service->videos->listVideos('snippet', $queryParams)->getItems();
$channelId = $response[0]->snippet['channelId'];
$channelTitle = $response[0]->snippet['channelTitle'];
I'm assuming that only channels with videos uploaded by the channel owner will be of interest. This is accidentally convenient since my method doesn't work with 0 video channels anyway.
Given a channel's url, my method will get the beautifulsoup HTML object of that channel's videos tab, and scrape the HTML to find the unique channel id. It'll then reconstruct everything and give back the channel url with the unique channel id.
your_channel_url = 'Enter your channel url here'
channel_url = your_channel_url.strip("https://").strip("featured")
https = "https://"
channel_vids_tab = https + channel_url + '/videos'
import requests
from bs4 import BeautifulSoup
source = requests.get(channel_vids_tab).text
soup = BeautifulSoup(source, "html.parser")
a = soup.find('body').find('link')['href']
channel_id = a.split('/')[-1]
print(a)
print(channel_id)
This method bypass the headache of one channel having different /user and /c url (for example /user/vechz and /c/vechz vs /c/coreyms and /user/schafer5 leading to the same page). Though you need to manually enter the url at first, it can be easily automated.
I'm also fairly confident that if a channel has 0 videos, this line of thinking can also apply for the playlist created BY the channel owner, and only needs a little tweaking. But if there's 0 videos or playlist created by the channel ... who knows
As #jkondratowicz noted, there is no way to reliably get this from the API as small channels do not return at the top of the search results.
So here is a JS example of how to get the channel id by extracting it from the HTML channel page (h/t #Feign'):
export const getChannelIdForCustomUrl = async (customUrl: string) => {
const page = await axios.get(`https://www.youtube.com/c/${customUrl}`)
const chanId = page.data.match(/channelId":"(.*?)"/)[1]
return chanId
}
Here is the .NET approach to convert custom Channel name/URL to a ChannelId using search API as mentioned in the accepted answer.
// https://www.youtube.com/c/TheQ_original/videos
// they call custom URL ?
// https://stackoverflow.com/questions/37267324/how-to-get-youtube-channel-details-using-youtube-data-api-if-channel-has-custom
// https://developers.google.com/youtube/v3/docs/channels#snippet.customUrl
// GET https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&q=annacavalli&type=channel&key={YOUR_API_KEY}
//
/// <summary>
/// Returns ChannelID from old "Custom Channel Name/URL"
/// Support the following URLs format
/// https://www.youtube.com/c/MakeYourOWNCreation
/// </summary>
/// <param name="ChannelName"></param>
/// <returns></returns>
// 20220701
public async Task<string> CustomChannelNameToChannelId(String ChannelName)
{
var YoutubeService = YouTubeService();
//
List<YouTubeInfo> VideoInfos = new List<YouTubeInfo>();
//
// -) Step1: Retrieve 1st page of channels info
var SearchListRequest = YoutubeService.Search.List("snippet");
SearchListRequest.Q = ChannelName;
SearchListRequest.Type = "channel";
//
SearchListRequest.MaxResults = 50;
// Call the search.list method to retrieve results matching the specified query term.
var SearchListResponse = await SearchListRequest.ExecuteAsync();
// According to the SO post the custom channel will be the first one
var searchResult = SearchListResponse.Items[0];
//
// Return Channel Information, we care to obtain ChannelID
return searchResult.Id.ChannelId;
}
I have to retrieve all video of my channel with Youtube API.
All videos are published on Youtube and I can see them correctly.
I tried to make the request directly from this page:
https://developers.google.com/youtube/v3/docs/search/list
and this is the example request:
GET http s://www.googleapis.com/youtube/v3/search?part=snippet&channelId=myChannelID&maxResults=50&key={YOUR_API_KEY}
Request doesn't retrieve all videos, it returns only 7 on the total of 9.
All videos have the same configuration. Missing videos are always the same.
If I use the video API passing the ID of one of those videos excluded from the search response, it returns a correct response and it belong correctly to my channel:
https://developers.google.com/youtube/v3/docs/videos/list#try-it
Someone can help me?
thank you in advance
Francesco
The answer to "How do I obtain a list of all videos in a channel using the YouTube Data API v3?" here may be what you need. Look especially at the video linked to in the answer.
To summarize, to get all the uploads from a channel, you need to get the items from the uploads playlist for the channel using playlistItems.list on that playlist's ID rather than calling search.list on the channel ID.
Try this two-step approach:
Get the ID of your channel's uploads playlist using the channels.list API call: GET https://www.googleapis.com/youtube/v3/channels?part=contentDetails&id={YOUR_CHANNEL_ID}&key={YOUR_API_KEY}
Get the videos from the uploads playlist using the playlistItems.list call: GET https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=3&playlistId={YOUR_PLAYLIST_ID}&key={YOUR_API_KEY}
try this
async static Task<IEnumerable<YouTubeVideo>> GetVideosList(Configurations configurations, string searchText = "", int maxResult = 20)
{
List<YouTubeVideo> videos = new List<YouTubeVideo>();
using (var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = configurations.ApiKey
}))
{
var searchListRequest = youtubeService.Search.List("snippet");
searchListRequest.Q = searchText;
searchListRequest.MaxResults = maxResult;
searchListRequest.ChannelId = configurations.ChannelId;
searchListRequest.Type = "video";
searchListRequest.Order = SearchResource.ListRequest.OrderEnum.Date;// Relevance;
var searchListResponse = await searchListRequest.ExecuteAsync();
foreach (var responseVideo in searchListResponse.Items)
{
videos.Add(new YouTubeVideo()
{
Id = responseVideo.Id.VideoId,
Description = responseVideo.Snippet.Description,
Title = responseVideo.Snippet.Title,
Picture = GetMainImg(responseVideo.Snippet.Thumbnails),
Thumbnail = GetThumbnailImg(responseVideo.Snippet.Thumbnails)
});
}
return videos;
}
}
How to get video id from youtube playlist in as3, in order to play latest uploaded video from you tube playlist.
I have load pLay List and it plays properly but I want to play only latest video from play list.
Thank you
You can use the Youtube Data API to fetch information about the items in a playlist.
In order to be able to use the API, you need to generate an API key. Info about how to do so can be found here.
To get the latest video in a certain playlist you can make a GET request for this URL:
https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails&maxResults=1&playlistId={YOUR_PLAYLIST_ID}&key={YOUR_API_KEY}
Let's break it down to see what it does:
https://www.googleapis.com/youtube/v3/playlistItems - This is the URL endpoint to request data about playlist items in the Youtube Data API
?part=contentDetails - We define what details we want returned from the query. In this case we want the video id's, so we use contentDetails
&maxResults=1 - We are only interested in one item - the latest. (It appears that the result is ordered from latest to oldest, so by only requesting the first video it should return the latest.)
&playlistId={YOUR_PLAYLIST_ID} - Replace this value with the ID of the playlist in question.
&key={YOUR_API_KEY} - Replace this value with your API key.
Let's look at a sample request:
var playlistUrl:String = "https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails&maxResults=1&playlistId=PL4Sz7_l-PtwAG8xye4Y9whykc4OAwbN9f&key={YOUR_API_KEY}"
var playlistReq:URLRequest = new URLRequest(playlistUrl);
var playlistLoader:URLLoader = new URLLoader();
playlistLoader.addEventListener(Event.COMPLETE, handlePlaylistUrlLoaded);
playlistLoader.load(playlistReq);
function handlePlaylistUrlLoaded(e:Event):void {
trace(playlistLoader.data); // See the response below
var playlistResponse:Object = JSON.parse(playlistLoader.data); // Parse the JSON response
trace(playlistResponse.items[0].contentDetails.videoId); // Prints "21Ox58OKFmo" which is the video id of the latest video in this playlist
}
The raw response to this sample query is:
{
"kind": "youtube#playlistItemListResponse",
"etag": "\"FOuwADrXJjsTKgUIQJoQC6nKNFY/n3kL7MtTJyPOfHU6jmro9gAC1CI\"",
"nextPageToken": "CAEQAA",
"pageInfo": {
"totalResults": 189,
"resultsPerPage": 1
},
"items": [
{
"kind": "youtube#playlistItem",
"etag": "\"FOuwADrXJjsTKgUIQJoQC6nKNFY/aNpryIHyioAUu4C9_WVP8kZGbuE\"",
"id": "PL88DYY_1F2muJ4Dv0iAFHEuKQuma2y_BH0WbF7AzESJw",
"contentDetails": {
"videoId": "21Ox58OKFmo"
}
}
]
}
Edit in response to further details
If you want to use the YouTube player API, it seems like you have to wait for a "video cued" event after adding the playlist to the cue.
So, in essence, this should work (untested code):
youtubePlayer.addEventListener("onStateChange", onPlayerStateChange);
youtubePlayer.cuePlaylist("{YOUTUBE_PLAYLIST_ID}");
function onPlayerStateChange(event:Event):void {
if (Object(event).data == YT.PlayerState.CUED) {
// Playlist cued, the playlist data should now be accessible
var playlist:Array = youtubePlayer.getPlaylist();
trace(playlist[0]); // This value should now exist
}
}
I want to use auto-generated channel Ids as example below...
GET https://www.googleapis.com/youtube/v3/channels?part=snippet&id=UCrfjym-5AEUY2QzXsddRIQA&fields=items(id%2Csnippet)&key={YOUR_API_KEY}
...to access their video contents. But seems I cannot make use of the part: 'snippet,contentDetails', or filter:'uploads' filtering method as I use for getting normal user channel Ids before grabbing their playlistItems. Is there a simple method to display video feed or playlist contents of an auto-generated channel? I use the gapi.client instead of the url. Thx for guidance.
FINAL UPDATE:
Here is my solution for auto-generated Topic-based channel ids, since I'm using
gapi.client, here's what works (relevant code only - URL samples below):
function requestUserUploadsPlaylistId(pageToken) {
var itemId = $("#YOUR-TEXT-INPUT").val(CHANNEL-ID); // Topic-based channel Id
var request = gapi.client.youtube.playlists.list({ // Use playlists.list
channelId: itemId, // Return the specified channel's playlist
part: 'snippet',
filter: 'items(id)' // This gets what you only need, the playlist Id
});
request.execute(function(response) {
playlistId = response.result.items[0].id;
requestVideoPlaylist(playlistId, pageToken); // Now call function to get videos
});
}
function requestVideoPlaylist(playlistId, pageToken) {
var requestOptions = {
playlistId: playlistId,
part: 'id,snippet',
maxResults: 6
};
var request = gapi.client.youtube.playlistItems.list(requestOptions);
request.execute(function(response) { // playlistItems.list is used here
. . .
Here's the URL sample of auto-generated Topic-based Id which grabs its playlist id:
GET https://www.googleapis.com/youtube/v3/playlists?part=snippet&channelId=HC9m3exs6zk1U&fields=items%2Fid&key={YOUR_API_KEY} // Outputs sample playlist Id: LP9m3exs6zk1U
Now here's the URL sample using that playlist Id to get the videos from the auto-generated Topic-based channel Id:
GET https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=5&playlistId=LP9m3exs6zk1U&key={YOUR_API_KEY} // Outputs video data you want.
Remember, Topic-based channel Ids come in different lengths, the above samples support current available lengths.
Hope This Helps!