Display Video on Apple Watch WatchKit - watchkit

Can any one know how to display .mp4 movie on Apple Watch ?
I have checked with other urls from apple as well this page
But not getting any clue about to display video on apple watch.
So, is it possible to display mp4 video on apple watch or it is not possible.

As mentioned in jessica's answer, you can play a video in a separate full-screen modal view, using WKInterfaceMovie object.
watchOS 3 adds a WKInterfaceInlineMovie object which plays a movie in place within the current interface.
Apple has updated their WatchKit Catalog sample code to include a MovieDetailController example demonstrating how to play an inline movie in place of a poster image:
class MovieDetailController: WKInterfaceController {
#IBOutlet var movie :WKInterfaceMovie!
#IBOutlet var inlineMovie :WKInterfaceInlineMovie!
#IBOutlet var tapGestureRecognizer :WKTapGestureRecognizer!
var playingInlineMovie :Bool = false
override func awake(withContext context: AnyObject?) {
super.awake(withContext: context)
// Obtain a URL pointing to the movie to play.
let movieURL = Bundle.main().urlForResource("Ski1", withExtension: "m4v")
// Setup the `movie` interface object with the URL to play.
movie.setMovieURL(movieURL!)
// Provide a poster image to be displayed in the movie interface object prior to playback.
movie.setPosterImage(WKImage(imageName: "Ski1"))
// Setup the `inlineMovie` interface object with the URL to play.
inlineMovie.setMovieURL(movieURL!)
// Provide a poster image to be displayed in the inlineMovie interface object prior to playback.
inlineMovie.setPosterImage(WKImage (imageName: "Ski1"))
// Movie playback starts
playingInlineMovie = false
}
#IBAction func inlineMovieTapped(sender : AnyObject) {
if playingInlineMovie == false {
inlineMovie.play()
} else {
inlineMovie.pause()
}
playingInlineMovie = !playingInlineMovie
}
}

The current WatchKit SDK does not support video playback. The closest you'd get is if you created an animated image using the frames in your video and transferred it to the Watch. In addition to a slow transfer, the frame rate would be pretty low, and you'd have no audio. Nowhere close to ideal.

i have tried using openParentApplication:reply: called from the extension in conjunction with application:handleWatchKitExtensionRequest:reply: delegate invoked by the app delegate in the ios app (to respond to the extension).
these two functions allow you to pass dictionaries back and forth between the app and the watch extension.
i call openParentApplication:reply: which allows me to pass a dictionary and then application:handleWatchKitExtensionRequest:reply: is automatically invoked, and when that's finished it invokes a callback from openParentApplication:reply:
i basically create a loop out of this.
i am able to get nsstrings and nsnumbers (a counter) passed back to the extension from the app delegate. the loop executes pretty quickly in the simulator (however i don't see it being much slower out side of the simulator, as the extension code resides on the iphone as well, according to my understanding of the documentation).
anyway, once i try to add a uiimage to this equation (to the dictionary in the callback), the entire dictionary gets received as nil in the extension callback (no nsnumber anymore, and no nsstring).
it seems perhaps the os is intentionally blocking video attempts like this (manually image framing).
if anyone else has any ideas, i would love to hear them.
i haven't tried 'handoffs' yet.

Video is possible with WKInterfaceMovie in watchOS 2
"A WKInterfaceMovie object lets you play back video and audio content directly from your interface. For audio and video assets played directly from your app, keep your clips relatively short. Short clips consume less space on disk, use less power, and take less time to download."
https://developer.apple.com/library/prerelease/watchos/documentation/WatchKit/Reference/WKInterfaceMovie_class/index.html

Related

A-Frame: How to provide sound fadeout to eliminate audio click upon sound termination

A-frame provides easy to use and powerful audio capabilites via its <sound> component.
After playing around with various sound options such as native html5 for my game (in progress), I came to the conclusion that A-frame sound is the best option because it automatically provides spatialized sound (e.g. that varies with head rotation), as well as varying in intensity as you near the sound source -- things that increase VR presence and all for the cost of defining a simple html tag.
Unfortunately, A-frame doesn't provide a fadeout utility to taper the sound upon stoppage, and thus can generates a distinctly audible and annoying click on some waveforms, esp. sounds that are of variable length and not tapered in the waveform itself (for instance, a space ship's thrust). This is a well known problem with computer audio.
I was able to find some html5 audio solutions and a really good three.js audio three.js audio solution, but I could find none specific to A-frame.
What's the best way to taper out a sound in A-frame to reduce/eliminate this click?
Introduction
A-frame sound audio wraps the three.js positional audio API, which in turns wraps native html 5 audio. Most solutions out there are tailored for either pure html5 or for pure three.js. Since A-frame is a hybrid of the two apis, none of the provided solution are great fits for A-frame.
After two false starts at coming up with something, I disovered tween.js, which is not only built-in to A-frame (don't even have to download the library), but is also a useful API to know for other forms of computer animation. I provide the main solution here as well as a plunker in the hopes that others can find something useful.
Note that you don't need to do this for short burst sounds like bullets firing. These sounds have a fixed lifetime, so presumably whoever creates the waveform makes sure to taper them in and out. Also, I only deal with fade out, not fade in becuase the sound I needed only had problems with fadeout. A general solution would include fadein as well.
Solution
1) We start off with creating a real basic scene onto which we can our audio:
<a-scene>
<a-assets>
<audio id="space-rumble" src="https://raw.githubusercontent.com/vt5491/public/master/assets/sounds/space-rumble.ogg" type="audio/ogg"></audio>
crossorigin="anonymous"
type="audio/ogg"></audio>
</a-assets>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"
sound="src: #space-rumble; volume: 0.9"
></a-box>
</a-scene>
The cube and scene in this solution are really just placeholders -- you don't need to enter VR mode to click the buttons and test the sound.
2) The code presents three buttons: one to start the sound, one to "hard" stop it using the A-frame default, and a third to "easy" stop it using tween to taper it down to zero. A fourth input allows you to vary the taper time. While it might look like quite a bit of code, keep in mind about 50% is just html boilerplate for the buttons, and is not part of the solution "proper":
// created 2017-10-04
function init() {
let main = new Main();
}
function Main() {
let factory = {};
console.log("entered main");
factory.boxEntity = document.querySelector('a-box');
factory.sound = factory.boxEntity.components.sound;
factory.volume = {vol: factory.sound.data.volume};
factory.boxEntity.addEventListener('sound-loaded', ()=> {console.log('sound loaded')});
factory.startBtn =document.querySelector('#btn-start');
factory.startBtn.onclick = ( function() {
this.sound.stopSound();
let initVol = factory.sound.data.volume;
this.volume = {vol: initVol}; //need to do this every time
this.sound.pool.children[0].setVolume(initVol);
console.log(`onClick: volume=${this.sound.pool.children[0].getVolume()}`);
this.sound.currentTime = 0.0;
if( this.tween) {
this.tween.stop();
}
this.sound.playSound();
}).bind(factory);
factory.hardStopBtn =document.querySelector('#btn-hard-stop');
factory.hardStopBtn.onclick = (function() {
this.sound.stopSound();
}).bind(factory);
factory.easyStopBtn =document.querySelector('#btn-easy-stop');
factory.easyStopBtn.onclick = (function() {
let sound = factory.sound;
this.tween = new TWEEN.Tween(this.volume);
this.tween.to(
{vol: 0.0}
, document.querySelector('#fade-out-duration').value);
this.tween.onUpdate(function(obj) {
console.log(`onUpdate: this.vol=${this.vol}`);
sound.pool.children[0].setVolume(this.vol);
console.log(`onUpdate: pool.children[0].getVolume=${sound.pool.children[0].getVolume()}`);
});
// Note: do *not* bind to parent context as tween passes it's info via 'this'
// and not just via callback parms.
// .bind(factory));
this.tween.onComplete(function() {
sound.stopSound();
console.log(`tween is done`);
});
this.tween.start();
// animate is actually optional in this case. Tween will count down on it's
// own clock, but you might want to synchronize with your other updates. If this
// is an a-frame component, then you can just use the 'tick' method.
this.animate();
}).bind(factory);
factory.animate = () => {
let id = requestAnimationFrame(factory.animate);
console.log(`now in animate`);
let result = TWEEN.update();
// cancelAnimationFrame is optional. You might want to invoke this to avoid
// the overhead of repeated animation calls. If you are putting this in an
// a-frame 'tick' callback, and there's other tick activity, you
// don't want to call this.
if(!result) cancelAnimationFrame(id);
}
return factory;
}
Analysis
Here are some relevant items to be aware of.
Mixed API's
I am calling some native A-frame level calls:
sound.playSound()
sound.stopSound()
and one html5 level call:
this.sound.currentTime = 0.0;
but most of the "work" is in three.js level calls:
this.sound.pool.children[0].setVolume(initVol);
This does make it a little confusing, but no single api is "complete" and thus I had to use all three. In particular, we have to do a lot at the level that is wrapped by A-frame. I learned most of this by looking at the aframe source for the sound component
Sound Pools
Aframe allows multiple threads for each sound, so that you can have the same sound fire off before the prior one has completed. This is controlled by the poolSize property on the sound component. I'm only dealing with the first sound. I should probably loop over the pool elements like so:
this.pool.children.forEach(function (sound) {
..do stuff
}
});
But doing the first one has worked well enough so far. Time will tell if this is sustainable.
'this' binding
I chose to implement all the functionality using a factory object pattern, and not placing all the methods and variables in the global document space. This mimics the enviornment you would have if you're implementing in Angular2 or as a native A-frame component. I mention this because we now have callbacks nested inside function nested inside a wrapping "main" function. Thus be aware that "this" binding can come into play. I bound most of the support functions to the factory object, but do not bind the tween callbacks, as they are passed information in their "this" context, and not passed via parms. I had to resort to closures for the callbacks to get access to the instances variables of the containing class. This is just standard javascript "callback hell" stuff, but just keep in mind it can get confusing if you're not careful.
canceled animation
If you have a tick function already, use that to call TWEEN.update(). If you're only fading out sound, then it's overkill to have an animation loop running all the time, so in this example I dynamically start and stop the animation loop.
tween can be chained.
Tweens can be chained in jquery fluent API style as well.
Conclusion
Using tween.js to phase out the sound definitely feels like the right solution. It takes care of a lot of the overhead, and design considerations. It also feels much faster, smoother, and robust than the native html5 calls I previously used. However, it's pretty obvious that it's not trivial to get this working at the application level. A fadeout property, implemented in Tween.js, seems like it should be part of the A-frame sound component itself. But until that time, maybe some people will find some of what I provide here useful in some form. I'm only currently learning about html audio myself so apologies if I'm making this seem harder than it really is.

Asp.Net Asynchronous Http Handler for Image Resizing

I am using c# method Image.GetThumbnail() to generate thumbnail of an Image. I have to generate this thumbnail dynamically. I have to generate 100 thumbnails for a single galleryId. So I added an HttpHandler to generate the thumbnail dynamically. The problem is when I click a gallery Id There is 100 request goes to my Http handler. So the thumbnails loads very slowly. I have some questios
Can I get the performance improvement with the implementation of Asynchronous Http Handler? I am not familiar with the asynchronous programming in c#. How Can I generate thumbnail using Http Asynchronous Handler?
Is there any alternative way to get better performance than asynchronous programming model? I mean add multiple handlers for serving the request like
Can anyone please help me.
Another way to solve this problem is to avoid it in the first place.
Generate the thumbnail when the image is uploaded and then just serve the ready thumbnail with content expiry set appropriately.
You will save quite a lot of processing and, what is more important, shift it in time, so when users are viewing the gallery you can serve the thumbnail as quickly as possible.
Here you need to define the real issue of the delay. Is because you call it 100 times at the same moment, or is because your handler is blocked by session lock ?
So first think is to remove the session from your handler - if you use it.
Second, if your problem is because you call it many times together you can limit this by using mutex and a simple trick. You can lock the handler to simulate only create let say 6 thumbnails simultaneously using mutex.
Here is a simple code that use mutex and can left at the same time n threads to run
static var random = new Random(DateTime.Now.Ticks);
public void ProcessRequest_NoCatch (HttpContext context)
{
// here we made names like ThubNum_0, ThubNum_1, ThubNum_2 ... ThubNum_4
// with 4 you have average 4 simulated thubs
string sMyMutexName = string.Format("ThubNum_{0}", random.Next(0, 4))
var mut = new Mutex(true, sMyMutexName);
try
{
// Wait until it is safe to enter.
mut.WaitOne();
// here you create your thubs
}
finally
{
// Release the Mutex.
mut.ReleaseMutex();
}
}
See how session block each other pages:
Web app blocked while processing another web app on sharing same session
Replacing ASP.Net's session entirely
cache
Of cource you need to cache your thumbnail's to the disk, and set also cache for the images for the browser. There is no reason to create them again and again.

how to manage windows in external applications

I have 2 AIR applications (A and B) that are able to communicate via a LocalConnection object. I've verified that messages are definitely being sent/received appropriately.
I want to be able to have A tell B to come to the front. Both applications are full screen:
stage.fullScreenSourceRect = new Rectangle(0, 0, 1080, 1920);
stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
I've tried several permutations, but as of yet nothing seems to work.
private function initSlave(channel: String): void {
conn = new LocalConnection();
conn.client = {
'activateSlave': activateSlave
};
conn.allowDomain("*");
conn.connect("_" + channel);
}
private function activateSlave(): void {
stage.nativeWindow.orderToFront();
// or
stage.nativeWindow.activate();
// or
stage.nativeWindow.alwaysInFront = true;
stage.nativeWindow.alwaysInFront = false;
}
If I leave both applications in windowed mode (stage.displayState = StageDisplayState.NORMAL), then toggling alwaysInFront actually works. Calling activate() or orderToFront() still do nothing. If I try to toggle alwaysInFront and then set the application to fullscreen, the application ends up fullscreen behind my windowed app. Maybe there is an event I should wait for before setting the app to fullscreen?
I found a thread mentioning that orderToFront() only works relative to windows within the same application, which explains why it doesn't seem to do anything.
Does anyone have any insights into pulling this off? Maybe there is a way for me to embed B into application A so they are actually the same application? I am not sure how to do this with an AIR application as simply as just loading the SWF due to requiring external resources.
As no one else has offered a solution, I'll just mention quickly the hack that I'm using. Basically I have 2 LocalConnection channels, one from A to B, and one from B to A.
The visible program (e.g. A) will then fade to white, set visible to false, and send a message to B giving up control. B has initialized itself with stage.nativeWindow.visible = false, and when it receives the message from A it goes visible as a full white screen and fades in the GUI. There is a slight offset before A sets visible to false to give B time to display, otherwise there is a pop in the brief moment when both windows are minimized.
Anyway, there you go, it's ugly but it actually works fairly well.

AVURLAsset loadValuesAsynchronouslyForKeys, synchronous version?

is there a way to load an AVURLAsset in a synchronous manner?
My scenario is one which I need to load the assets in the background while showing a different view and change to the view showing the AVPlayer when the assets are ready to play. Not before.
I've tried loading async and calling a delegate method to tell "the assets are ready, you can show the next view", but if I get a mem warning before that, the views containing the assets in the background get released before they finish loading...so i never get the delegate call. That's why I rather do it synchronously.
Any ideas?
I'm not 100% sure I understand what you're getting at, but I believe you should be able to just use [AVURLAsset commonMetadata] or [AVURLAsset metadataForFormat:[[AVURLAsset availableMetadataFormats] lastObject]] and then show your view once this information has been loaded. Theses methods return an array of AVMetadataItems, which you should rather easily be able to traverse with a for loop. Sorry if this wasn't what you were looking for.

Forcing Flex to update the screen?

This may be a bit of a beginners question, but I can't for the life of me figure it out.
I'm using flex to develop a GUI for a large project, specifically a status bar along the bottom. Within my StatusBar class is a ProgressBar, which other classes doing work can tell to update(change bar completion and label) as they progress. The problem I'm encountering is that flex won't update whats shown on the screen until it's too late, for example
ProgressBar initialized, 0% done
some class sets the ProgressBar to be 12% done
some class does some work
some class sets the ProgressBar to be 56% done
Whats happening is the 12% done is never displaying, it just hangs at 0% during the work, then skips right to 56% done. I've tried to understand the lifecycle of a flex component (invalidation and validation), and I think I understand it and am applying it correctly, but it's not working at all. I need to tell flex to redraw my StatusBar (or at least the ProgressBar within) after some class sets it to be 12% done, but before some class starts doing its work. How do I do this?
As mentioned in other answers, the flash player is single threaded, if you don't break up your work into discrete chunks that can be executed in separate "frames", you're going to see jumps and stutters in the ui, which is effectively what you're seeing.
If you really must see that 12% message, then it's not enough to invalidate the display list, as the display list isn't getting a chance to update until after the 56% work has completed, you must explicitly interrupt the natural event cycle with a call to validateNow() after your message has been set.
This however is not the best way to do things if performance is of concern. You might get by with judicial usage of callLater() to schedule each chunk of work in turn, as this will allow the player to potentially complete a frame cycle (and update the display list) before attempting the next step in your process.
Glenn,
That is not at all how the threading in Flex works whatsoever. Like many UIs it has a message pump on the main UI thread (they do it in frames). When you call callLater() it places the passed in function pointer at the end of the message pump queue (on the next frame) and returns immediately. The function then gets called when the message pump has finished processing all of the messages prior (like mouse clicks).
The issue is that as the property change causes UI events to be triggered, they then place their own messages on the pump which now comes after your method call that you placed there from callLater().
Flex does have multiple threads but they are there for Adobe's own reasons and therefore are not user accessible. I don't know if there is a way to guarantee that a UI update will occur at a specific point, but an option is to call callLater a number of times until the operation occurs. Start off with a small number and increase until the number of iterations produces the result you want. Example:
// Change this to a number that works... it will probably be over 1, depending on what you're doing.
private const TOTAL_CALL_COUNT:int = 5;
private var _timesCalled:int = 0;
//----------------------------------------------------------------
private function set Progress( progress:int ):void
{
progressBar.value = progress;
DoNextFunction();
}
//----------------------------------------------------------------
private function DoNextFunction():void
{
if( _timesCalled >= TOTAL_CALL_COUNT )
{
_timesCalled = 0;
Function();
}
else
{
_timesCalled++;
callLater( DoNextFunction );
}
}
Try calling invalidateDisplayList() after each changes to your progress bar. Something like :
Class StatusBar
{
public function set progress(value:uint):void
{
progressBar.value = value;
progressBar.invalidateDisplayList();
}
}
Flex has an invalidation cycle that avoid screen redrawing everytime a property changes. As an example, if a property's value changes 3 times in a single frame, it will render only with the last value set. You can force a component to be redrawn by calling invidateDisplayList() which means updateDisplayList will be immediatly executed instead of waiting the next frame.
Actionscript in Flash player, like Javascript in the browser, is pseudo-multithreaded. That is, they're single threaded, but they have multiple execution stacks. This means you can't "sleep" in a particular thread, but you can spawn a new execution stack that gets deferred until a later time. The flex way of doing this is the "callLater" function. You can also use the setTimeout/setInterval functions. Or you can use a timer object built into the flash player. Or even "ENTER_FRAME" event listener. All of these will essentially allow you to do what you need, if I'm correct about the cause of your problems.
It sounds like you have one "thread" doing most of your work, never stopping to allow other execution stacks (threads*) to run.
The problem could be what PeZ is saying, but if that doesn't help, you might want to try some deferred calls for worker classes. So your process might look like this now:
Progress initialized.
Do some work.
Update progress bar to 12. (invalidate display list)
setTimeout(doMoreWork, 100);
Update progress bar to 52.
(if your worker is a UIcomponent, you can use uicomp.callLater(...), otherwise, you need to use setTimeout/timers/enter_frame for pure AS3 classes).
Sometimes its necessary set to zero before assign another value.
progressBar.setProgress(0, progressBar.maximum);
progressBar.setProgress(newValue, progressBar.maximum);
I'm using Flash Builder 4.6 and I also have a problem for the display of my progress bar. I open a new window where I start a new multiloader class (39 Mo of content). The new window is opened in background and the main window display a progress bar until the multiloader class has finished his work. However the opening window is blocking the animation of my main window. I know it's not the multiloader class cause I saw it running correctly.
But I will try to find some new ways of doing it.
The main purpose of my post is the complexity adobe has build around flash.
When you seek ressources for your own application or answers for your questions, it's a real pain to find the good ressource. There is a total mix up (at adobe side and at user side) between AS3, Flex, Flash CS, Flash Builder, AiR, ... If you try to develop in AS3, you will find that some examples won't work for you because it is not implemented in your SDK. You have more and more forums giving you the "best practice" or ironic answers based on experiences on different developping platform.
By example, just here above, I see progressBar.value = value; With my experience, I can say that in Flash Builder 4.6, this property is read-only. But It might be a custom class made by the user but who can tell.

Resources