I want to get youtube videos from youtube api using json request. Now i get videos from youtube using json. Example the url have some deleted videos (http://www.youtube.com/watch?v=MlOHWLqgcoY&list=PLD62D6701B15FD3E1) but i get only playing videos not deleted videos. Is it possible or any other way to handle youtube deleted videos using json results.
This is my code to get youtube videos
string getPlaylistVideoUrl = https://gdata.youtube.com/feeds/api/playlists/PLD62D6701B15FD3E1?v=2&safeSearch=strict&orderby=position&start-index=1&max-results=25&alt=json;
var webRequest = (HttpWebRequest)WebRequest.Create(getPlaylistVideoUrl);
using (WebResponse response=await webRequest.GetResponseAsync())
using (Stream responseStream=response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
var jsonResult = reader.ReadToEnd();
var videosList = JsonConvert.DeserializeObject<YouTubeVideosByPlaylist>(jsonResult);
if (videosList.Feed != null)
{
if (videosList.Feed.Entry != null)
{
//Add entries to class
}
}
Thanks in advance.
i solve the youtube deleted videos problem. if you get the playlist to given format=6 in the youtube api Url.
string getPlaylistVideoUrl = https://gdata.youtube.com/feeds/api/playlists/PLD62D6701B15FD3E1?v=2&safeSearch=strict&orderby=position&start-index=1&max-results=25&alt=json&format=6;
Videos that are not playable will normally have app$control elements set in their JSON response when retrieved using v2 of the Data API. Here's an example of what to look for in your response JSON:
"app$control": {
"app$draft": {
"$t": "yes"
},
"yt$state": {
"$t": "This video is not available in your region.",
"name": "restricted",
"reasonCode": "requesterRegion"
}
}
There are other reasons why a video might not be playable in a given playback scenario, so the absence of app$control doesn't ensure that the video can always be played. But if app$control is there, then the video can't be played.
From the Google documentation "If a video is not playable, the entry for that video will not contain a <media:content> tag. In addition, the entry may contain an <app:control> tag that contains an explanation of why the video is not playable"
https://developers.google.com/youtube/2.0/developers_guide_protocol_testing
Related
I want to update my snippet.description on my Youtube channel using the API exposed through Google Apps Script. I know the videoId already so there is no need to create and loop through a search list like they show in the example here.
I expect to see my script complete with the new description on my Youtube video. But I get the following error message instead.
API call to youtube.videos.update failed with error: Forbidden (line 90, file "Youtube")
Code.gs
function updateVideo( data ) {
var videoId = 'foo';
var title = 'bar';
var description = 'baz';
var resource = {
id: videoId,
snippet: {
title: title,
description: description,
categoryId: '22'
}
};
YouTube.Videos.update(resource, 'id,snippet'); // this is line 90
}
What am I doing wrong?
Note
To clarify: By "only the videoId", I mean without creating a list of channels to find it like they do here.
var myChannels = YouTube.Channels.list('contentDetails', {mine: true});
Edit
This question is different because the other asks specifically about HTML. This question is not about using HTML in the description. It's about making any changes whatsoever to the description.
Summary from comments:
This is an authorization error. The account making the API request was not the same account as the owner of the YouTube video.
I want to update my Youtube video snippet.description from the API exposed through Google Apps Script. The snippet contains formatting so I am trying to use HTML. I expect to see the updated snippet on my Youtube video. But I get the following error instead.
API call to youtube.videos.update failed with error: The request metadata specifies an invalid video description. (line 88, file "Youtube")
How can I format my video description?
Youtube.gs
function updateVideo( data ) {
var videoId = 'foo';
var title = 'bar';
var description = '<p>baz</p><p>bat</p>';
var resource = {
id: videoId,
snippet: {
title: title,
description: description,
categoryId: '22'
}
};
YouTube.Videos.update(resource, 'id,snippet'); // this is line 88
}
You can't use HTML so you have to use string symbols for newline \n and tab \t, etc.
var description = 'baz\n\nbat';
I don't know how to add other HTML features like links, etc. Maybe someone else can improve upon this answer by adding that information if they know how to do it.
I was using the YouTube search API to retrieve live videos by channel ID, but recently, the API has begun to return an empty response.
For example, I am retrieving from https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&eventType=live&key={YOUTUBE_KEY}&channelId=UCPde4guD9yFBRzkxk2PatoA which should return all videos which are live from channelID = UCPde4guD9yFBRzkxk2PatoA. This channel has a 24/7 live stream, but the response I get back is:
{
"kind": "youtube#searchListResponse",
"etag": "\"8jEFfXBrqiSrcF6Ee7MQuz8XuAM/-f6JA5_OcXz2RWuH1mpAA2_9mM8\"",
"regionCode": "US",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 5
},
"items": []
}
As I mentioned before, this request was retrieving data fine up until recently. I was unable to find any changes on the YouTube API docs, so I'm wondering if anyone has any idea on what changed or if there's a different approach I can take to pull live videos by channel ID.
Not an answer, but it seems that endpoint isn't returning ANY recent videos that would include live. From what I can tell it doesn't return anything published in the previous 24 hours.
Found an open issue on Google Support
https://support.google.com/youtube/thread/14611425?hl=en
As an alternative, instead, you could load "uploads" playlist,
check https://stackoverflow.com/a/27872244/2154075
try this code
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;
}
}
As 8/2020 there some changes in the API and you need to add &type=video or add it to your post request otherwise in some cases you will get empty or random response from the endpoint
for the older channels you may get the right response and it seems to be a bug in the API
https://www.googleapis.com/youtube/v3/search?key={your_key_here}&channelId={channel_id_here}&part=snippet&order=date&maxResults=20&type=video
I am having a requirement of creating a playlist of selected media(both audio and video) from local machine using HTML5 media tags. I am using the below code
http://jonhall.info/how_to/create_a_playlist_for_html5_audio
Now the problem am facing is in this line
extension = audio.canPlayType('audio/mpeg') ? '.mp3' : audio.canPlayType('audio/ogg') ? '.ogg' : '';
it only plays audio files if i change it to video/mp4 it plays video files only if i use if else then also the first condition is working
if(audio.canPlayType('video/mp4')) {
extension = '.mp4';
}
else if
(audio.canPlayType('audio/mpeg')) {
extension = '.mp3';
}
Please help me out what could be the condition I can put here to play both type of media in playlist and also if possible I can switch video/audio tag with the type of media selected.
THANKS IN ADVANCE
To use both video and audio in a playlist you should use the html5 video tag instead of the audio tag. You do not need to switch back and forth. The video tag will play both audio and video files.
In order to use the code from the site listed, you will need to know whether you are loading a video or an audio file. Then you can determine the correct extension to use based on browser support found in the script. See the new html5 video and audio playlist example below:
http://jonhall.info/examples/html5_video_audio_playlist_example.html
In the new example I replaced the code:
extension = audio.canPlayType('audio/mpeg') ? '.mp3' : audio.canPlayType('audio/ogg') ? '.ogg' : '';
with a function:
getExtension = function(type) {
extension = '';
if(type === 'a') {
if(video.canPlayType('audio/mpeg')) {
extension = '.mp3';
}
if(video.canPlayType('audio/ogg')) {
extension = '.ogg';
}
}
if(type === 'v') {
if(video.canPlayType('video/mp4')) {
extension = '.mp4';
}
if(video.canPlayType('video/ogg')) {
extension = '.ogv';
}
}
return extension;
};
Pass the letter 'a' for audio or the letter 'v' for video.
I am using Google Place Api where is on some results "photo_reference" (similar to "reference") value. I cannot find any mention about that how to use it to get that photo. I know how to use "reference" to get PlaceDetail and I am sure that usage of photo_reference will be similar, but I cannot find JSON/XML URL for this photo_reference request. Thank you for any help. Pavel
Please take a look at documentation here: https://developers.google.com/places/documentation/photos
They've just announced this new Place Photos feature
In short this is how you should use this new feature:
https://maps.googleapis.com/maps/api/place/photo?photoreference=PHOTO_REFERENCE&sensor=false&maxheight=MAX_HEIGHT&maxwidth=MAX_WIDTH&key=YOUR_API_KEY
just substitute your own values in place of:
PHOTO_REFERENCE
MAX_HEIGHT - int value from 1 to 1600
MAX_WIDTH - int value from 1 to 1600
YOUR_API_KEY
and you are done
The Places API now supports the return of one place photo if available for a Place Search request and up to ten place photos for a Place Details request.
If a photos array is returned with your request, you can pass the photo_reference from a contained photo object to a Place Photo request with the maxheight and/or maxwidth, sensor and key parameters:
https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CnRvAAAAwMpdHeWlXl-lH0vp7lez4znKPIWSWvgvZFISdKx45AwJVP1Qp37YOrH7sqHMJ8C-vBDC546decipPHchJhHZL94RcTUfPa1jWzo-rSHaTlbNtjh-N68RkcToUCuY9v2HNpo5mziqkir37WU8FJEqVBIQ4k938TI3e7bf8xq-uwDZcxoUbO_ZJzPxremiQurAYzCTwRhE_V0&sensor=false&key=AddYourOwnKeyHere
Please see the documentation for more details.
please bear in mind that there are no free photo requests anymore.
At this moment (November 2020), it is $7.0 for 1000 requests (if your volume is up to 100,000). Check the photo below.
Read more on Google Places billing info page.
Step 1: The URL you should use to call Google Place Photos is :
String url = https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=PHOTOREF&key=YOUR_API_KEY
Refer: https://developers.google.com/places/web-service/photos
Step 2: Since the above URL redirects to another URL, use HTTPClient, as it automatically handles redirect stuff.
Code:
DefaultHttpClient hc = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
HttpContext context = new BasicHttpContext();
hc.setRedirectHandler(new DefaultRedirectHandler() {
#Override
public URI getLocationURI(HttpResponse response,
HttpContext context) throws org.apache.http.ProtocolException {
//Capture the Location header here - This is your redirected URL
System.out.println(Arrays.toString(response.getHeaders("Location")));
return super.getLocationURI(response,context);
}
});
// Response contains the image you want. If you test the redirect URL in a browser or REST CLIENT you can see it's data
HttpResponse response = hc.execute(httpget, context);
if(response.getStatusLine().getStatusCode() == 200) {
// Todo: use the Image response
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
Bitmap bmp = BitmapFactory.decodeStream(instream);
ImageView imageView = new ImageView(context);
imageView.setImageBitmap(bmp);
images.add(imageView);
instream.close();
}
}
else {
System.out.println(response.getStatusLine().getStatusCode()+"");
}
Hope this helps everyone.
After initiating map you can get place details with it's images
const service = new window.google.maps.places.PlacesService(map);
service.getDetails(
{
placeId: "some_place_id_here"
},
(data, status) => {
if (status === window.google.maps.places.PlacesServiceStatus.OK) {
data.photos &&
data.photos.forEach(photo => {
console.log(photo.getUrl({ maxWidth: 500, maxHeight: 500 }));
});
}
}
);
Solving the PhotoReference issue for Javascript
User #R.K solved this issue in java, however in js you need to use fetch(). Here's the code I used:
await fetch(proxyUrl+url).then(async(ref)=>{
await ref.blob()}).then((image)=>{
// do what you need to do
console.log(image)
}).catch((err)=>{
console.log(err);
})
In this, I used a heroku link for the proxyUrl and the url shown in #Chriss Green's post for url. Hope this helps anyone confused using js!