I am streaming small movies (1-3MB) off my website into my iPhone app. I have a slicehost webserver, I think it's a "500MB slice". Not sure off the top of my head how this translates to bandwidth, but I can figure that out later.
My experience with MPMoviePlayerLoadStateDidChangeNotification is not very good.
I get much more reliable results with the old MPMoviePlayerContentPreloadDidFinishNotification
If I get a MPMoviePlayerContentPreloadDidFinishNotification, the movie will play without stuttering, but if I use MPMoviePlayerLoadStateDidChangeNotification, the movie frequently stalls.
I'm not sure which load state to check for:
enum {
MPMovieLoadStateUnknown = 0,
MPMovieLoadStatePlayable = 1 << 0,
MPMovieLoadStatePlaythroughOK = 1 << 1,
MPMovieLoadStateStalled = 1 << 2,
};
MPMovieLoadStatePlaythroughOK seems to be what I want (based on the description in the documentation):
MPMovieLoadStatePlaythroughOK
Enough data has been buffered for playback to continue uninterrupted.
Available in iOS 3.2 and later.
but that load state NEVER gets set to this in my app.
Am I missing something? Is there a better way to do this?
Just making sure that you noticed it's a flag, not a value?
MPMoviePlayerController *mp = [aNotification object];
NSLog(#"LoadState: %i", (NSInteger)mp.loadState);
if (mp.loadState & MPMovieLoadStatePlaythroughOK)
{
// Do stuff
}
Related
I need to analyse one http event value which should not be greater than 30mins. & 95% event should belong to this bucket. If it fails send the alert.
My first concern is to get the right metrics in /actuator/prometheus
Steps I took:
As in every http request event, I am getting one integer value called eventMinute.
Using micrometer MeterRegistry, I tried below code
// MeterRegistry meterRegistry ...
meterRegistry.summary("MINUTES_ANALYSIS", tags);
where tag = EVENT_MINUTE which receives some integer value in each
http event.
But this way, it floods the metrics due to millions of event.
Guide me a way please, i am beginner to this. Thanks!!
The simplest solution (which I would recommend you start with) would be to just create 2 counters:
int theThing = //getTheThing()
if(theThing > 30) {
meterRegistry.counter("my.request.counter.abovethreshold").inc()
}
meterRegistry.counter("my.request.counter.total").inc()
You would increment the counter that matches your threshold and another that tracks all requests (or reuse another meter that does that for you).
Then it is simple to setup a chart or alarm:
my_request_counter_abovethreshold/my_request_counter_total < .95
(I didn't test the code. It might need a tiny bit of tweaking)
You'll be able to do a similar thing with DistributionSummary by setting various SLOs (I'm not familiar with them to be able to offer one), but start with something simple first and if it is sufficient, you won't need the other complexity.
There are certain ways to solve this problem
1 ; here is a function which receives tags, name of metrics and a value
public void createOrUpdateHistogram(String metricName, Map<String, String> stringTags, double numericValue)
{
DistributionSummary.builder(metricName)
.tags(tags)
//can enforce slo if required
.publishPercentileHistogram()
.minimumExpectedValue(1.0D) // can take this based on how you want your distibution
.maximumExpectedValue(30.0D)
.register(this.meterRegistry)
.record(numericValue);
}
then it produce metrics like
delta_bucket{mode="CURRENT",le="30.0",} 11.0
delta_bucket{mode="CURRENT", le="+Inf",} 11.0
so as infinte also hold the less than value, so subtract the le=30 from le=+Inf
Another ways could be
public void createOrUpdateHistogram(String metricName, Map<String, String> stringTags, double numericValue)
{
Timer.builder(metricName)
.tags(tags)
.publishPercentiles(new double[]{0.5D, 0.95D})
.publishPercentileHistogram()
.serviceLevelObjectives(new Duration[]{Duration.ofMinutes(30L)})
.minimumExpectedValue(Duration.ofMinutes(30L))
.maximumExpectedValue(Duration.ofMinutes(30L))
.register(this.meterRegistry)
.record((long)timeDifference, TimeUnit.MINUTES);
}
it will only have two le, the given time and +inf
it can be change based on our requirements also it gives us quantile.
I've been trying to figure this out for the past day or two with minimal results. Essentially what I want to do is send my selected comps in After Effects to Adobe Media Encoder via script, and using information about them (substrings of their comp name, width, etc - all of which I already have known and figured out), and specify the appropriate AME preset based on the conditions met. The current two methods that I've found won't work for what I'm trying to do:
https://www.youtube.com/watch?v=K8_KWS3Gs80
https://blogs.adobe.com/creativecloud/new-changed-after-effects-cc-2014/?segment=dva
Both of these options more or less rely on the output module/render queue, (with the first option allowing sending it to AME without specifying preset) which, at least to my knowledge, won't allow h.264 file-types anymore (unless you can somehow trick render queue with a created set of settings prior to pushing queue to AME?).
Another option that I've found involves using BridgeTalk to bypass the output module/render queue and go directly to AME...BUT, that primarily involves specifying a file (rather than the currently selected comps), and requires ONLY having a single comp (to be rendered) at the root level of the project: https://community.adobe.com/t5/after-effects/app-project-renderqueue-queueiname-true/td-p/10551189?page=1
Now as far as code goes, here's the relevant, non-working portion of code:
function render_comps(){
var mySelectedItems = [];
for (var i = 1; i <= app.project.numItems; i++){
if (app.project.item(i).selected)
mySelectedItems[mySelectedItems.length] = app.project.item(i);
}
for (var i = 0; i < mySelectedItems.length; i++){
var mySelection = mySelectedItems[i];
//~ front = app.getFrontend();
//~ front.addItemToBatch(mySelection);
//~ enc = eHost.createEncoderForFormat("H.264");
//~ flag = enc.loadPreset("HD 1080i 25");
//app.getFrontend().addItemToBatch(mySelection);
var bt = new BridgeTalk();
bt.appName = "ame";
bt.target = "ame";
//var message = "alert('Hello')";
//bt.body = message;
bt.body="app.getFrontend().addCompToBatch(mySelection)";
bt.send();
}
}
Which encapsulates a number of different attempts and things that I've tried.
I've spent about 4-5 hours trying to scour the internet and various resources but so far have come up short. Thanks in advance for the help!
I've been trying to control 4 MAX7219 controlled 8x8 LED arrays, totaling a 8x32 "screen". they are daisy chained, as seen here.
From what I've gathered, I have to send data for all of my arrays; each MAX7219 will process his own data, and the remaining data will "overflow" to the next MAX7219 to process.
This works very nicely when I address only one "row" of my screen: First row getting and displaying the data as intended
The code to achieve it is the following:
write = function(register, data) {
let buf = new Buffer([register, data]);
this.spi.write(buf, (device, buf2) => {
let s = "";
for (let i = 0; i < buf.length; i++)
s = s + buf[i] + " ";
});
}
(from the NPM SPI documentation)
Writing the data:
write(0x01, 0x01);
write(0x01, 0x03);
write(0x01, 0x07);
write(0x01, 0x0F);
The issues start, when I try and write to the second row. Sending the data to the second row messes with the first one, but I just can't wrap my head around to why this happens.
write(0x01, 0x01);
write(0x01, 0x03);
write(0x01, 0x07);
write(0x01, 0x0F);
// Writing to the second row
write(0x02, 0x80);
write(0x02, 0xC0);
write(0x02, 0xE0);
write(0x02, 0xF0);
This results in a second row that looks like it should but a first row that is messed up:
Second row OK, First row messed up
This happens with any combination of rows. The last one is OK, while the previous ones are messed up.
I don't know why other rows get all messed up, when they're not getting written to, beyond the data transfer that is confirmed to be working...
Notes: I'm using a Raspberry Pi Model B+ V1.2 with Raspbian; Node.js v8.11.1;
After studying a few other repositories, (special thanks to bitbank2's great C++ repo), and I've created an NPM Package to do exactly what I wanted it to do:
Control Multiple daisy-chained MAX7219 8x8 LED arrays, in a very simple way.
You can find the Github repository here, and the NPM Package here.
We are working on Universal Windows Apps in which we are opening the files (whose size is 20MB) using below code.
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.FileTypeFilter.Add(".abc");
StorageFile file = await openPicker.PickSingleFileAsync();
if (file == null) return false;
FlowSheetFilePath = file.Path;
LaunchQuerySupportStatus status = await Launcher.QueryFileSupportAsync(file);
if (status == LaunchQuerySupportStatus.Available)
{
bool didLaunch = await Launcher.LaunchFileAsync(file);
if (didLaunch)
{
}
}
In the above code, Is there any way to determine how much time is needed to completely open the file whose size is around 20MB?
It's not possible. Note that this will depend not only on device configuration/type but ola CPU overload and so on.
If your app read/processes the file you may implement some kind of ProgressBar that will indicate how much work is already done (with implementation of IProgress<>) and how much is left, however that also won't help you with determination of time - you can think of estimating the time left basing on that what is already done, but this is only estimation and will surely change over time. But this won't also help you with Launcher.LaunchFileAsync(file).
I have searched extensively on how to loop a sound effect with simple audio engine, but haven't made much progress apart from hello with looping sfx on the cocos2d forum which has several issues. How can I loop a sound effect in Simple Audio Engine?
You would need to edit the SimpleAudioEngine
add this to SimpleAudioEngine.h
-(int) playEffect:(NSString*) file loop:(BOOL) loop;
add this method to SimpleAudioEngine.m
-(int) playEffect:(NSString*) file loop:(BOOL) loop
{
int handle = [[SimpleAudioEngine sharedEngine] playEffect:file];
if (loop) {
alSourcei(handle, AL_LOOPING, 1);
}
return handle;
}
to loop sound effects or music simply do this
ALuint yourSoundALuint = [[SimpleAudioEngine sharedEngine] playEffect:#"yourSound.caf" loop:YES];
and to stop the looping music when necessary
[[SimpleAudioEngine sharedEngine] stopEffect:yourSoundALuint]
For Sound Effect Infinite Looping until you want it to stop.
This is how you do it without messing up anything else.
Make Sure you save the CDSoundSource strong reference in the class or object that is using it so that way you are able to stop it whenever you want.
Since its a unique ID that identifies that sound effect, and this way you can have multiple instances of this sound effect running.
For example: when you need 2 helicopters and each with its own infinite engine sounds.
//Create SFX
-(CDSoundSource*)playInfiniteHeliPad
{
CDSoundSource *loopSound = [[SimpleAudioEngine sharedEngine] soundSourceForFile:#"Sound.m4a"];
loopSound.looping = YES;
loopSound.gain = 0.5f;//Volume
[loopSound play];
return loopSound; //Return the CDSoundSourse
}
//Stop Infinite loop SFX.
-(void)stopInfiniteHeliPad:(CDSoundSource*)loopSound {
[loopSound stop];
}
This is easy to implement and require no modification to root files from Cocos2Denshion