YouTube JavaScript API: use of "unstarted" state - youtube-api

From the player documentation: "When the player first loads a video, it will broadcast an unstarted (-1) event."
What's the intended use of this event? That is, what would my host code do differently, as a consequence of seeing it, than it would if the state didn't exist? The example code I've seen does nothing but log it.

I don't imagine that it's very useful. I don't think there's some deeper truth that you're missing out on. I assume it reflects a state that's mainly used internally by the player itself and it was exposed in the API for the sake of completeness.

Might be a good way to detect if autoplay is enabled. I.e. "unstarted" would happen on platforms that don't support autoplay but was attempted, but "playing" would be the event for other systems.

I've been finding the -1 tripping up some of my logic so decided to just ignore it and hope for the best.
I actually see a sequence of -1, 3, -1 with less than 1ms between each event. So if your logic depends any sort of state machine transitions between states you may need to consider that.
Also watch out for this if you explicitly use stopVideo()
Important: Unlike the pauseVideo function, which leaves the player in
the paused (2) state, the stopVideo function could put the player into
any not-playing state, including ended (0), paused (2), video cued (5)
or unstarted (-1).
Generally you should use pauseVideo() which according to this won't result in -1.

Related

What is the difference between a <prompt> element appearing inside a <block> vs a <field>?

Current understanding:
To my understanding, the functionality of a <prompt> element is to define prompt audio to be played, followed by the system waiting for a user utterance. My impression comes from the VoiceXML 2.0 specification for prompts:
Conceptually, prompts are instantaneously queued for play, so interpretation proceeds until the user needs to provide an input. At this point, the prompts are played, and the system waits for user input.
Additionally, I understand the difference between a <block> and a <field> to be that:
a <block> is a control item and is "not for gathering input", and
a <field> is an input item whose value is "gather[ed] from the user"
Lastly, I know that a <prompt> can be a direct child of both a <block> and <field>.
Questions:
I am pretty sure that a <prompt> collects input when inside a <field>, but what is supposed to happen when it is inside a <block>, since blocks are control items?
In the case that a <prompt> in a <block> does not collect input and only plays audio, why wouldn't you instead write the text for a prompt as content inside a <block>, omitting the <prompt>?
There is no difference.
1 - It is the field that is driving the input process, not the prompt. Try it without the prompt.
2 - If you aren't using any of the other features of the prompt element, it doesn't matter.
Note, there is something important to realize in the text you quoted. "prompts are instantaneously queued" Prompt and similar element structures just queue audio. Yes, you will usually start to hear them if there is a delay. But, the playback is separate from the element.
As far as to why you might do one over the other, it could just be development style or flow based logic. For example, when playing back data, having multiple blocks that can be jumped through to cover different scenarios might be cleaner that a complex field/prompt configuration.

Get duration of video with AVFoundation

To get the duration of an AVPlayerItem I could do: player.currentItem.duration.
Instead of this, I could also get the duration from my backend as an Int. Then I can convert this to a Float to be used anywhere I need the duration for. I think this might be better in terms of performance and less work on my end to get the duration.
For example Apple says this about getting duration:
“A vital concept in AV Foundation is that initializing an asset or a
track does not necessarily mean that it is ready for use. It may
require some time to calculate even the duration of an item (an MP3
file, for example, may not contain summary information). Rather than
blocking the current thread while a value is being calculated, you ask
for values and get an answer back asynchronously through a callback
that you define using a block.”
Any thoughts on things that could go wrong if I decide to hardcode the duration by getting it from the server? Is this good practice?
If you already know the value on your backend, and you're already making call to say get the video URL, retrieving the duration seems a reasonable idea.
Although - is there any chance of a mismatch? If you do it client side it's "guaranteed" to be correct.
If you have to make a special call to get it, I wouldn't as it's likely to take much longer than determining it during asset initialisation.

UIImpactFeedbackGenerator impactOccurred Slight Delay

I'm using UIImpactFeedbackGenerator as described in Apple's developer docs, but there seems to be a slight delay -- maybe a tenth of a second or similar -- between when I invoke impactOccurred and when you feel the haptic. This is especially evident when I am playing a sound at the same time - the sound clearly precedes the haptic.
Someone else wrote about the same thing in Apple Developer Forums, but no resolution.
I initialize the UIImpactFeedbackGenerator with:
// Set up impact
UIImpactFeedbackStyle sty = UIImpactFeedbackStyleMedium;
impactFeedbackGen = [[UIImpactFeedbackGenerator alloc] initWithStyle:sty];
Immediately call prepare, and call repeatedly during the few seconds that pass before the impact occurs:
[impactFeedbackGen prepare];
Then finally play the haptic, with:
[impactFeedbackGen impactOccurred];
Not sure if it's related, but I am using UISelectionFeedbackGenerator in the same app, but not at the same time.
Thoughts?
Thanks!
I think the trick with avoiding delay with UIImpactFeedbackGenerator is when to call prepare.
Obviously you can't simply call prepare and then immediate trigger the impact, since the engine needs time to actually prepare.
On the other hand, once prepare is called, the taptic engine will only stay in a prepared state for a short duration (a matter of seconds), in order to conserve power.
It is possible to extend the prepared state by calling prepare multiple times, however you have to be careful here as well, since after a certain threshold, the system will put the engine back to an idle state, and ignore further calls to prepare until after an impact is triggered.

HTML5 video seeking on iPad

I have an HTML5 video player with a custom seek bar, that's working great on the iPhone (playing inline) and on the browser.
It plays great on the iPad too and the seek bar is updated as the movie plays, but for some reason, I can't seek.
All of the values are correct and I'm trying to set:
myPlayer.currentTime = XX;
Unfortunately, the iPad refuses to set the .currentTime attribute.
From what I can gather the difference between the browser and iPad is that on the browser I get:
myPlayer.networkState = 3
myPlayer.readyState = 4
On the iPad I get:
myPlayer.networkState = 2
myPlayer.readyState = 3
It's exactly the same code, running a local MP4 video.
Any idea why this is happening?
Cheers,
Andre
I've had all kinds of problems getting JavaScript to control audio elements, and a lot of frustration with the currentTime property, along with Apple's restrictions on what constitutes direct user initiation of events.
It wouldn't surprise me if there were some kind of weird bug with JavaScript & HTML5 video playback on the iPad (or "feature" that's undocumented), which requires a workaround. From my experience, the iPad has a unique way of doing things than what's in the official documentation.
You should check the error, buffered, seekable, and seeking properties of the video element. Looking at your readyState & networkState values, the iPad seems to think that the video has not been completely loaded - which is odd for a local resource.
buffered and seekable should be equal to the time range of your entire video. seeking should be TRUE. That should at least give you a little more information about the problem.
Have you tested it with other videos? It might be that there is some kind of encoding problem with the video that the iPad has a problem with.
Other than that - there was a bug in a previous iPad OS version that broke the ability to set the currentTime property. Are you using the latest OS version?
This issue is related with value used on the video.currentTime property. On my specific case I fixed the problem by always making sure I was using floating point numbers with 1 decimal digit during the seek.
Setting video.currentTime to ZERO on iOS 3.2 will indeed seek the video to the beginning but the value won't update after that - timeupdate event is still dispatched normally but if you try to read currentTime it will always return the same value.
To seek to the begin of the video use 0.1 instead of 0, to seek to 12.2345 use 12.2.
PS: you can use (+(12.2345).toFixed(1)) to limit the number of decimal digits to 1.
Kyle's answer is a good one. I would add, you can't assume the seekable attribute is filled in after any particular event. This means you can't wait for events like loadedmetadata, canplay, or any other and assume that you're able to set currentTime safely at that point.
It seems the safest way to do it is to check seekable after every video-related event, and if it encompasses the time you want to seek to, set currentTime at that point. On iPad, seekable may not be filled until after the canplaythrough event, which is quite late.
See my blog post for more on this.
I am having the same issue - here are the properties in my case:
UIWebView - iPad Simulator
duration=4.861666679382324
startTime=0
currentTime=4.861666679382324
buffered(1)=[0-0]
seekable(0)=
seeking=false
error=null
readystate=4
networkstate=3
Chrome:
duration=4.9226298332214355
startTime=0
currentTime=4.9226298332214355
buffered(1)=[0-4.9226298332214355]
seekable(1)=[0-4.9226298332214355]
seeking=false
error=null
readystate=4
networkstate=1
so - nothing is getting buffered and nothing is seekable. i am playing a local clip from the resources directory of an iPad bundle, via a UIWebView.
In my case, all i need is to reset to the top of the video after each play, and I was able to accomplish this via a call to "load()"

How do you make a combo of two emotes in lua in World of Warcraft work?

How do you make a combo of two emotes in lua in World of Warcraft work?
function Button2_OnClick()
PlaySoundFile("Interface\\Addons\\Fart\\common_fart[1].wav");
DoEmote("moon");
DoEmote("sit");
DoEmote("dance");
DoEmote("beckon");
end
I am using Wow Addon Studio to make a fart application on Wow.
I used this function, and only the sit motion showed, and beckon and moon only showed on the chat window. The dance emote didn't show up anywhere.
Blizzard has explicitly prohibited anything that can be used to make lua wait or pause because it is an essential ingredient to making a gold mining or grinding bot.
There isn't a native (i.e. lua only) way to have lua wait without using all the CPU. Outside of the WOW client, you'd use win.sleep or some other 3rd party API call that calls into the host application or operating systems threading functions.
It may be possible to simulate a wait by having code execute on a frequent event (such as text arriving at the chat window) and then in the event handler checking to see if enough time has passed to permit executing the next command in the sequence. This probably wouldn't be a very accurate timer and it would be rather complex as you'd have to create a data structure to hold the sequence of commands, the timings between each, the current command, etc. and so on.
This may be an intentional limitation of the API to prevent in game automation (botting).
What has worked for me is to have a global variable that is incremented through the loop. Such as
Integer count = 0;
function Button2_OnClick()
i++
switch
case(1)
PlaySoundFile("Interface\\Addons\\Fart\\common_fart[1].wav");
case(2)
DoEmote("moon");
case(3)
DoEmote("sit");
case(4)
DoEmote("dance");
case(5)
DoEmote("beckon");
default
i=0;
end
end
What you would have to do then is to click the button multiple times, but you would get the effect you're going for.
I would suggest you wait some time before doing the next emote. As far as I know, the server disconnects you if you spam too much. This might just trigger it sometimes.
Besides that, I guess maybe the client has a way of preventing it? In either case, I would suggest you add some sort of fraction-of-a-second delay between the emotes.
Cheers,
Amit Ron
Could it be that the last two can't be done while sitting?
infact, integer i = 0, because defining integer 'count' and then using i is incorrect. :)

Resources