Get current duration of YouTube Live Event - youtube

Is there a way to get the current time of a the recorded stream when broadcasting to YouTube live? I want to be able to send an API request at certain points throughout a live stream to get the current minute/second of the stream. The end result I am trying to achieve is to be able to log a list of highlights. Essentially, a user presses a button and it gets the current time of the stream at that moment, then the user can add a note for what happened at that time. From reading all the docs though, I cannot find a way to get the current time of the recorded stream.

Looks like you can do this with the iFrame API's getDuration() method.
https://developers.google.com/youtube/iframe_api_reference#getDuration
Check out the special note for live events:
If the currently playing video is a live event, the getDuration() function will return the elapsed time since the live video stream began. Specifically, this is the amount of time that the video has streamed without being reset or interrupted. In addition, this duration is commonly longer than the actual event time since streaming may begin before the event's start time.
You didn't specify a language, so I'll post code examples in two different languages. Both utilize the iFrame API.
JavaScript:
window.onYouTubePlayerReady = function(playerId) {
window.ytplayer = document.getElementById("ytPlayer");
console.log(window.ytplayer.getDuration());
}
Objective-C (using YouTube's youtube-ios-player-helper class)
#property (weak, nonatomic) IBOutlet YTPlayerView *playerView;
// ...
- (void)viewDidLoad {
[super viewDidLoad];
[[self.playerView loadWithVideoId:#"iGTIK_8ydoI"] // live at the time answer was posted
}
// ...
- (void)getDurationOfPlayingVideo {
NSLog(#"duration: %d", [self.playerView duration]);
}
Just as a disclaimer from my personal testing: the Live Streaming API is extraordinary temperamental and unstable, and I've found that some Live Events return a duration of 0.

this is old but you can get the liveStreamingDetails.actualStartTime through the youtube API.
With the actualStartTime in hands, you can calculate how much time elapsed.
"https://www.googleapis.com/youtube/v3/videos"
"?part=liveStreamingDetails"
"&id=$id&key=$_key"

Related

Get YouTube Live Stream total duration

I want to get the total duration of a current live stream on YouTube (not ended!). This is straightforward for normal videos, e.g.:
https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id={VIDEO_ID}&key={KEY}
However, for live streams such as Earth live from ISS this just returns a duration of "PT0S" which essentially means it's 0 seconds long.
There should be a way to get it. One way to get it is via Javascript, if you have the live stream open in your browser:
ytplayer = document.getElementById("movie_player");
console.log("Duration: " + ytplayer.getDuration());
Is it possible to get from a server-side? Other people have asked the same but have not received an answer yet.
Edit: I've just noticed the javascript way of getting the duration doesn't make any sense. For a live stream that started 2 hours ago, getCurrentTime() returns correctly 2*60*60=7200 when at the current time, but getDuration() returns 10245 for whatever reason.

Youtube API detecting advertisements

Is there a way to detect a youtube advertisement, when it is playing and also when it ends?
Something like:
function onPlayerStateChange(event) {
if(event.data == advertisement) {
console.log("Advertisement is playing");
}
if(event.data == advertisementIsOver) {
console.log("Advertisement has finished playing");
}
}
I see the question here:
What is the YouTube's PlayerState during pre-roll ad?
And am wondering if there are any updates to the youtube api? Also, can someone provide some code of a youtube advertisement detector? I am not sure how one reliably catches when an advertisement is playing.
A little late but better late than never...
I'm currently developing a chrome extension specifically targeted towards YouTube video playback manipulation. This is one method I've found to detect whether an ad is playing:
Note: All classes I use and Id's are subject to change as YouTube developers change them.
1) Get the html5 video element first: var mainVideo = document.getElementByClassName("html5-main-video"). No element Id for it at the moment but it always has the class html5-main-video.
2) Set an event handler for when the video is ready to play that will check whether or not it's an ad and will be fired when a new video is loaded and ready to play mainVideo.oncanplay = isVideoAnAd.
3) When an ad is playing the progress bar is yellow or more specifically rgb(255, 204, 0) and this property is easily comparable using jQuery
function isVideoAnAd () {
if($(".ytp-play-progress").css("background-color") === "rgb(255, 204, 0)
{
return true;
}}
For more reliable results you can also check the movie_player elements classList to see if it contains("ad-showing"). By the way, movie_player is the id.
Tip: I found all of this with inspect element
This is really the only reliable way I've found to detect ads without having to dive into the YouTube API.
You might want to check this documentation. It is stated that you can use onAdStarted() which is called when playback of an advertisement starts.
Here is a related forum and tutorial which might help.

Is it possible to get audio from an ICY stream with percentage and seek function

I'm trying to reproduce audio from an ICY stream. I'm able to reproduce that with AVPlayer and some good open source library but I'm not able to control the stream. I have no idea how I can get the percentage reproduced or how to seek to a specific time in the stream. Is that possible? Is there a good library that can help me?
Actually I'm using AFSoundManager but I'm always receiving negative numbers for percentage and I get invalid time when trying to seek the stream at a specified time.
That's the code that I'm using:
AFSoundManager.sharedManager().startStreamingRemoteAudioFromURL("http://www.abstractpath.com/files/audiosamples/sample.mp3") { (percentage, elapsedTime, timeRemaining, error, poppi) in
if error == nil {
//This block will be fired when the audio progress increases in 1%
if elapsedTime > 0 {
println(elapsedTime)
self.slider.value = Float(elapsedTime*1000)
}
} else {
//Handle the error
println(error)
}
I'm able of course to get the elapsedTime but not the percentage or the remainingTime. I always get negative numbers.
This code works perfectly with remote or local audio file but not with the stream.
This isn't possible.
These streams are live. There is nothing to seek to because what you haven't heard hasn't happened yet. Even streams that playback music end-to-end are still "live" in the sense that the audio you haven't received hasn't been encoded yet. (Small codec and transit buffers aside, of course.)

recording against a metronome of set length using remote IO

I was able to create the exact functionality I wanted to avaudioplayer and avaudiorecorder but of course experienced latency problems. So after reading pretty much every article on the web and reviewing stacks of sample code, I'm still not sure how to achieve the following:
User chooses to record a sample 2 bars long (4 beats per bar) with a pre-roll/count-in
User clicks record
A metronome starts which counts in 4 beats (accent on the first beat)
The app automatically starts recording on the start of the next bar
The app automatically turns off recording at the end of the 3rd bar (the 2 bars + the pre-roll)
The user can then playback their recording or delete it and start again.
So, with avaudioplayer and avaudiorecorder I simply created a 'caf' using audacity with a metronome set at the correct bpm (bpm is set for the app). I then setup and play the avaudioplayer and using the audiodidfinishsuccessfully delegate method, performed some logic to start the recorder, restart the player, maintain a loop count etc. to turn off recording and audio.
As I mentioned, I was pretty much able to achieve the user experience I am after but the latency problems are not acceptable.
I have been working with audio units and the remote IO and have setup a project with a playback callback and recorder callback etc. but now face the problem of working how to make this work based on the description above. I am trying to work out the following things for starters:
If I create a 1 beat caf file, how could I make use of audio units and remote IO to play x amount of beats and then stop?
How could I do the pre-roll and start the recording callback after 4 beats
Can anyone give me some ideas or point me in the right direction. As I have mentioned, I have already done a stack of research including buying the core audio book, reading every article on atastypixel.com, timbolstad.com etc and trawled through the apple docs.
Thanks in advance for your help.
I start an NSTimer. Use values based on BPM (Beats per Minute) / 60. So if user wants to record a 2 bar file with a count in might do something like this:
//timer interval=100BPM/60secs per minute
timerInterval=100/60;
metroTimer = [NSTimer scheduledTimerWithTimeInterval:timerinterval target:self selector:#selector(blinkMetroLight) userInfo:nil repeats:YES];
- (void)blinkMetroLight
{
if(beatNumber == 0)
{
beatNumber = 1;
}
else if (beatNumber == 5)
{
[self audioProcessorStart];
}
if (beatNumber == 8)
{
[self audioProcessorStop];
[metroTimer invalidate]; metroTimer = nil;
}
beatNumber++
}

ytplayer api event when reaching a position in a video?

Is there a way to cause an event when a video reaches a specific time? I want to get to a callback function at the time when the video has reached to a certain time, and the time it takes for the video to reach that time is unpredictable, since the user can skip part of the video, or buffering might take some time before the video resumes, or something like that, so simply setting a timed event wont work because the video might reach specific time earlier.
I can query the time of the video, but what I want is to get a callback when the video has reached a certain time. Is there a way to do this?
I'm not going to write the full code, but you should set up an interval, like this:
var time = 70; // Time in seconds, e.g. this one is one minute and 10 seconds
var reached = false;
var interval = setInterval(function(){
if(player.getCurrentTime() >= time && !reached) {
clearInterval(interval);
reached = true;
timeReached();
}
},1000);
function timeReached() {
// Do what you have to
}
You can use this Javascript wrapper for the YouTube player API.
The API provides very simple event handling. E.g:
youtubePlayer.at('5000', function() {
alert("You're five seconds into this Youtube clip");
});
use player.getCurrentTime()!
https://developers.google.com/youtube/iframe_api_reference#Playback_status

Resources