Using the youtube javascript api (http://code.google.com/apis/youtube/js_api_reference.html), I am trying to allow a user to embed a video into some content he creates in my app. I have gotten everything working, except for being able to detect and handle the case that embedding is not allowed for the video.
Currently, the player loads and shows a thumbnail of the disallowed video, and it only gives an error once the user tries to play it. This is bad because the user may not play the video before saving / sending his content. I would like to preemptively detect that the video is not allowed to be embedded, and display a helpful message to the user.
The only solution I can see is to actually play it (programmatically) and handle the error that is raised at that point.
Existing workaround:
Embed player (embedSWF)
onYouTubePlayerReady(): add onError onStateChange event listeners.
onStateChange(newState): when the video finishes loading, try to play it.
e.g. if (newState == 5 /* CUED */) { player.mute(); player.playVideo(); player.stopVideo(); player.unMute(); }
onError(error): if the video failed to play in onStateChange, will receive error here.
Is there a better way?
Thanks!
-Rob
You can grab the JSON feed for that video entry before you embed it and see if "yt$format":5 exists, which is the embed SWF. It won't be there if embedding is disabled.
http://gdata.youtube.com/feeds/api/videos/video_id?v=2&alt=json-in-script
I think that you might be looking for the videoSyndicated or the videoEmbeddable parameter. The API documentation says:
videoEmbeddable
The videoEmbeddable parameter lets you to restrict a search to only videos that can be embedded into a webpage. If you specify a value for this parameter, you must also set the type parameter's value to video.
Reference: https://developers.google.com/youtube/v3/docs/search/list#videoEmbeddable
videoSyndicated
The videoSyndicated parameter lets you to restrict a search to only videos that can be played outside youtube.com. If you specify a value for this parameter, you must also set the type parameter's value to video.
Reference: https://developers.google.com/youtube/v3/docs/search/list#videoSyndicated
Example Call
With both:
GET https://www.googleapis.com/youtube/v3/search?&part=snippet,statistics&videoSyndicated=true&videoEmbeddable=true&key=${yourKey}
I know this isn't directly to the question, but in case someone using PHP stumbles upon this problem, there's a method getNoEmbed() in a Zend_Gdata_YouTube_VideoEntry.
Taken from the docs:
If the return value is an instance of Zend_Gdata_YouTube_Extension_NoEmbed, this video cannot be embedded.
Related
I'm working on a tvOS application where I'm using the AVPlayer to play an HLS playlist which provides audio in two formats for some languages. For example:
French (AAC)
French (EC-3)
English
I'm trying to display a custom dialog that would allow the users to select between each of these tracks.
The playlist looks like this:
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-mp4a.40.2",NAME="Français",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fr",URI="..."
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-ec-3",NAME="Français",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="fr",URI="..."
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-mp4a.40.2",NAME="English",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="en",URI="..."
The problem is that, from what I can tell, the AVPlayer groups the tracks by language and it never returns all the 3 tracks.
(lldb) po player?.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .audible)
▿ Optional<AVMediaSelectionGroup>
- some : <AVAssetMediaSelectionGroup: 0x283961940, options = (
"<AVMediaSelectionKeyValueOption: 0x2839a5a00, language = fr, mediaType = 'soun', title = Français, default = YES>",
"<AVMediaSelectionKeyValueOption: 0x2839a5b00, language = en, mediaType = 'soun', title = English>"
), allowsEmptySelection = YES>
I went deeper into the French item (player?.currentItem?.asset.mediaSelectionGroup(forMediaCharacteristic: .audible)?.options.first) but I still couldn't find anything useful. I also tried looking at other fields from the AVPlayer with no success.
Even when I use the AVPlayerViewController I only see two audio tracks to choose from.
Is there any way to get all the available audio tracks?
So the issue here is actually the playlist. If you check the HLS specification, there are some notes explaining this under the Rendition Groups subsection of EXT-X-MEDIA (https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-07#section-4.4.6.1.1)
A Playlist MAY contain multiple Groups of the same TYPE in order to
provide multiple encodings of that media type. If it does so, each
Group of the same TYPE MUST have the same set of members, and each
corresponding member MUST have identical attributes with the
exception of the URI and CHANNELS attributes.
Generally, the way to think about it is, anything within a given GROUP-ID is selectable by the user (and so AVFoundation reveals it to you). But which GROUP-ID is playing is selected by the player, and (for this scenario) this is determined by the AUDIO attribute of the EXT-X-STREAM-INF that the player has selected.
If you want the surround audio track to be selectable, then it needs to exist in the same GROUP-ID as the rest of the AUDIO tracks. If you don't have control of the manifest, you can test this by re-writing the GROUP-ID of the surround French track (using something like Charles Proxy), from audio-ec-3 to audio-mp4a.40.2; it should appear in AVFoundation after that. But a word of warning, for the HLS to remain valid, the CODECS attribute of all of the EXT-X-STREAM-INF tags have to be updated to include the CODECS defined by the surround track (otherwise playback failure may occur).
If you want to leave it up to the player to select, and you do not have a surround English track, you still have to give the English option in the surround group to remain valid HLS, but you can just leave the URI identical to the one defined in the stereo group. Again CODECS will have to be updated in this scenario.
This video from WWDC gives a good explanation of all of this (relevant section starts around 42:39): https://developer.apple.com/videos/play/wwdc2018/502/
I have two "Live streaming/live broadcast saved playlists" in following youtube channel --> https://www.youtube.com/user/swaminarayanlive.
I am trying to retrieve all the "live streaming / live broadcast playlists" of a channel using new youtube v3 api by using the below link-->
https://www.googleapis.com/youtube/v3/playlists?part=snippet&channelId=UCBkNpeyvBO2TdPGVC_PsPUA&key={YOUR_API_KEY}
here i can get the info of playlists which are not live streams or live broadcast. and not able to get the same for the live one.
Please help me how can i get that for live one using youtube v3 api
I was researching another issue with the API when finding this, and when I saw that this was never resolved, I decided to look into it. It turns out that this is related to that other issue.
The YouTube API v3 lacks support for saved playlists. The channel swaminarayanlive did not create the playlists, only saved them from the channel BhujMandir.
The workaround in your case would be to retrieve the playlists of BhujMandir and extract the response snippets with "title" parameters containing the word "Live".
You would need to go through the pages and search each one for this, since there is a limit to how many results an API response can show at once. Currently it's 50.
So, you would use the following to get the first page of playlistItems:
GET https://www.googleapis.com/youtube/v3/playlists?part=snippet&channelId=UCVItNtUctAknegvmYcMhUQg&maxResults=50&key={YOUR_API_KEY}
This will return an API response containing the properties "kind" (which will have the value "youtube#playlistListResponse") and "etag". If there are more than 50 results, there will also be a "nextPageToken" property. (On a page that is not the first, there would also be a "prevPageToken" property.)
After these properties, there are two blocks. One called "pageInfo", containing info about how many results (playlists) there are and how many are shown per page, and one block called "items", containing the resulting playlistItems.
You would look through the items block for any playlistItem with a title property (which is a string) containing the substring "Live" and get the id properties of those. You would then look on the next page by using the nextPageToken's value in a new HTTP request, like so:
GET https://www.googleapis.com/youtube/v3/playlists?part=snippet&channelId=UCVItNtUctAknegvmYcMhUQg&maxResults=50&pageToken=[nextPageToken_value_here]&key={YOUR_API_KEY}
As of now, the two playlists you're looking for are on the pages with tokens CJYBEAA and CMgBEAA.
I think that where is the {YOUR_API_KEY} you should change this code and insert the name of your application program interface
I have an iOS app that goes to youtube and gets videos. I want to make it to where it only returns videos from a vevo channel. What is the API link I would use in order to do this? This is my data link:
http://gdata.youtube.com/feeds/api/videos/%#?alt=json
How would I change this link to get vevo-only videos.
Also, if there isn't a way for the above, is there a way to make it return a query with a permanent string? e.g. q=Hozier + "Audio"
Hozier = What the user inputed
Audio = The permanent string.
Essentially whatever the user inputs is followed by audio
I have a medialibrarypickerfield, I've added a youtube video to it.
How can I get access to the YouTube video URL in an alternate at the following level:
MediaLibraryPicker-ContentType-VideoFieldName.cshtml
I've tried
var field = (MediaLibraryPickerField) Model.ContentField;
var contents = field.MediaParts;
to gain access to each MediaPart/video but when I iterate through the MediaParts, the MediaUrl is null. I know this has something to do with the OEmbedPart but I don't know how to access this.
Extremely frustrating so far. An otherwise very simple task outside of Orchard to store and retrieve URLs.
To access the oEmbed part, just do As<OEmbedPart>() on the media part. You can then access the URL for the video by using the Source property of the part. You can also access a number of properties that are provided by the oEmbed site (YouTube in your case). Those properties can be accessed using the indexer on the part.
For example, part["html"] will give you the html code to embed in your page to render the video player:
#Html.Raw(part["html"])
There is also a "thumbnail" or a "thumbnail_url" property (depending on provider) that will give you the url of a thumbnail image. You can look at the whole blob of XML underlying that in the Framework_ContentItemRecord table's Data column. There is also a width and a height for example.
I'm trying to figure out how I can specify a custom end time for an embedded YouTube video. I know that I can customize the start time by adding &start=30, but I haven't seen anything relating to the end time.
I need to be able to do this for a web app I'm building, so if there is no way provided by YouTube, how might I be able to accomplish this anyway?
I've skimmed over the documentation to no avail. Thanks!
I just found out that the following works:
https://www.youtube.com/embed/[video_id]?start=[start_at_second]&end=[end_at_second]
Note: the time must be an integer number of seconds (e.g. 119, not 1m59s).
I tried the method of #mystic11 ( https://stackoverflow.com/a/11422551/506073 ) and got redirected around. Here is a working example URL:
http://youtube.googleapis.com/v/WA8sLsM3McU?start=15&end=20&version=3
If the version=3 parameter is omitted, the video starts at the correct place but runs all the way to the end. From the documentation for the end parameter I am guessing version=3 asks for the AS3 player to be used. See:
end (supported players: AS3, HTML5)
Additional Experiments
Autoplay
Autoplay of the clipped video portion works:
http://youtube.googleapis.com/v/WA8sLsM3McU?start=15&end=20&version=3&autoplay=1
Looping
Adding looping as per the documentation unfortunately starts the second and subsequent iterations at the beginning of the video:
http://youtube.googleapis.com/v/WA8sLsM3McU?start=15&end=20&version=3&loop=1&playlist=WA8sLsM3McU
To do this properly, you probably need to set enablejsapi=1 and use the javascript API.
FYI, the above video looped: http://www.infinitelooper.com/?v=WA8sLsM3McU&p=n#/15;19
Remove Branding and Related Videos
To get rid of the Youtube logo and the list of videos to click on to at the end of playing the video you want to watch, add these (&modestBranding=1&rel=0) parameters:
http://youtube.googleapis.com/v/WA8sLsM3McU?start=15&end=20&version=3&autoplay=1&modestBranding=1&rel=0
Remove the uploader info with showinfo=0:
http://youtube.googleapis.com/v/WA8sLsM3McU?start=15&end=20&version=3&autoplay=1&modestBranding=1&rel=0&showinfo=0
This eliminates the thin strip with video title, up and down thumbs, and info icon at the top of the video. The final version produced is fairly clean and doesn't have the downside of giving your viewers an exit into unproductive clicking around Youtube at the end of watching the video portion that you wanted them to see.
Use parameters(seconds) i.e. youtube.com/v/VIDEO_ID?start=4&end=117
Live DEMO:
https://puvox.software/software/youtube_trimmer.php
Youtube doesn't provide any option for an end time, but there alternative sites that provide this, like
Tubechop. Otherwise try writing a function that either pauses video/skips to next
when your when your video has played its desired duration.
OR: using the Youtube Javascript player API, you could do something like this:
function onPlayerStateChange(evt) {
if (evt.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
Youtube API blog
Today I found, that the old ways are not working very well.
So I used:
"Customize YouTube Start and End Time - Acetrot.com"
from http://www.youtubestartend.com/
They provide a link into
https://xxxx.app.goo.gl/yyyyyyyyyy
e.g. https://v637g.app.goo.gl/Cs2SV9NEeoweNGGy9
Link contain forward to format like this
https://www.youtube.com/embed/xyzabc123?start=17&end=21&version=3&autoplay=1
I was just trying to look up how and found there is a CLIP feature now added by Youtube right under the video that I had never noticed before!
I use this signature:
youtube.com/embed/[YOUR_VIDEO_ID]?start=[TIME_IN_SEC]&end=[TIME_IN_SEC]&autoplay=1
https://www.youtube.com/embed/2EWejmkKlxs?start=1230&end=1246&autoplay=1