Can Media Source API appended buffer(range) be overwritten? - html

I did little investigation into Media Souce Extension/API but I haven't found a way for specific buffer to be overwritten. Lets say I have watched first 30 seconds with lower quality and player switched to higher quality after that, so 30-60 sec is HQ. So... when I seek back to seconds 0-30 I would get lower quality video (one already buffered), but I would like to re-append newly requested same range with higher quality and watch that. I've seen on existing players (MSE showcases) this is not the case.
I guess MSE determines where to append buffer based on (I cannot recall now for the name) start date time? So, is it possible to override some appended range/buffer in Media Source API ?

Yes, it's possible. Before you call appendBuffer() on a source buffer, set timestampOffset to the time in seconds you wish to start overwriting. For example:
var mediaSource = new MediaSource();
mediaSource.addEventListener('sourceopen', function() {
var sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
/* ...code to fetch low quality binary... */
sourceBuffer.appendBuffer(lowQualityBinary);
/* ...later fetch higher quality binary and overwrite
* entire video starting at the beginning...
*/
sourceBuffer.timestampOffset = 0;
sourceBuffer.appendBuffer(highQualityBinary);
});
Note that if the user is playing the video and you overwrite starting at a time prior to their current play time, the current behavior on Chrome is to continue showing the original appended video. If it's overwritten later, or they seek around, they'll see the new video.

Related

What governs playback speed when encoding with Android's MediaCodec + mp4parser?

I'm trying to record, encode and finally create a short movie on Android (using API 16) with a combination of MediaCodec and Mp4Parser (to encapsulate into .mp4).
Everything is working just fine, except for the duration of the .mp4: its always 3 seconds long - and runs at about twice the 'right' speed.
The input to encoder is 84 frames (taken 100ms apart).
The last frame sets the 'end of stream' flag.
I set the presentation time for each frame on queueInputBuffer
I've tried to tweak every conceivable parameter - but nothing seems to make a difference - the film is always 3 seconds long - and always played way too fast.
So what governs the playback seepd? how do I generate a film with 'natuarl' speed?
I figured it out: When encapsulating with mp4parser (needed if you target API<18), you need to set the speed in mp4parser's API. The presentation time you provide to queueInputBuffer appearently make no difference if you're not using Android's built-in muxer (available only from API18).
I stumbled on this question on github, which indicates the following is required:
new H264TrackImpl(new FileDataSourceImpl(rawDataFile), "eng", 100, 10);
the last two parameters (timeScale and frameTick) set the playback speed to 'noraml'.

x264 rate control modes

Recently I am reading the x264 source codes. Mostly, I concern the RC part. And I am confused about the parameters --bitrate and --vbv-maxrate. When bitrate is set, the CBR mode is used in frame level. If you want to start the MB level RC, the parameters bitrate, vbv-maxrate and vbv-bufsize should be set. But I don't know the relationship between bitrate and vbv-maxrate. What is the criterion of the real encoding result when bitrate and vbv-maxrate are both set?
And what is the recommended value for bitrate? Equals to vbv-maxrate?
Also what is the recommended value for vbv-bufsize? Half of vbv-maxrate?
Please give me some advice.
bitrate address the "target filesize" when you are doing encoding. It is understandably confusing because it applies a "budget" of certain size and then tries to apportion this budget on the frames - that is why the later parts of a movie get a smaller amount of data which results in lower video quality. For example, if you have 10 seconds of complete black images followed by 10 second of natural video - the final encoded file will be very different than if the order was the opposite.
vbv-bufsize is the buffer that has to be completed before a "transmission" would occur say in a streaming scenario. Now, let's tie this to I-frames and P-frames: the vbv-bufsize will limit the size of any of your encoded video frames - most likely the I-frame.

AS3 - how to change speed of FLVPlayBack

i need to play FLVPlayback Video at different speeds , can i do this by changing frame-rate of FLVPlayBack and how can i achieve this using as3?
Or is there any other method to do the same? Please Suggest me.
Meghana
There's no way to change the framerate of a video in AS3, it will be always rendered at the video's native framerate.
The only way I can think to do it is to write some sort of function that calculates how to move the playhead, but I cannot guarantee the result of this approach.....
EDIT:
As you ask in your comment, YES, you can do it by controlling the NetStream. Here you have the solution: http://younsi.blogspot.it/2009/03/how-to-play-video-in-flash-in-slow.html
Chiming in a bit late, but there's actually a way to play an FLV in slow motion without constantly seeking or playing/pausing repeatedly. It's just extremely involved.
If you open the .flv file using a URLStream then you can access the bits. Scan for the timestamp, re-write it, then pass the new ByteArray to a NetStream in data generation mode. Using this you can play video at any frame rate - although the ability to play audio in slow / fast motion depends on the codec being used. The layout of an FLV packet is something like:
"FLV"
packet length
packet type (audio / video / metadata)
timestamp
additional headers
data
To change the audio sample rate you would need to muck with the data - much more convoluted than just changing timestamps. I know, for instance, that AAC data has a header which specifies the sample rate as an index into an array:
[ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 ]
So if you had 44.1 kHz audio (sample rate index = 4) you could play at half speed by declaring the sample rate to be 22.05 kHz (sample rate index = 7)
//set your framerate here whatever you want
stage.frameRate = 30;
var FRAMERATE : Number = stage.frameRate;
btnActual.addEventListener(MouseEvent.CLICK, videoSpeed);
btn15.addEventListener(MouseEvent.CLICK, videoSpeed);
btn5.addEventListener(MouseEvent.CLICK, videoSpeed);
function videoSpeed (myEvent:Event):void{
var newFrameRate = Number(myEvent.target.value);
stage.frameRate = newFrameRate;
}

Unlimited Map Dimensions for a game in AS3

Recently I've been planning out how I would run a game with an environment/map that is capable of unlimited dimensions (unlimited being a loose terms as there's obviously limitations on how much data can be stored in memory, etc). I've achieved this using a "grid" that contains level data stored as a String that can be converted to a 2D Array that would represent objects and their properties.
Here's an example of two objects stored as a String:
"game.doodads.Tree#200#10#terrain$game.mobiles.Player#400#400#mobiles"
The "grid" is a 3D Array, of which the contents would represent the x/y coordinate of the grid cell. The grid cells would be, say, 600x600.
An example of this "grid" Array would be as follows:
var grid:Array = [[["leveldata: 0,0"],["leveldata 0,1"]],
[["leveldata: 1,0"],["leveldata 1,1"]]];
The environment will handle loading a grid square and it's 8 surrounding squares based on a given point. ie the position of the Player. It would have a function along the lines of
function loadCells(xp:int, yp:int):void
This would also handle the unloading of the previously loaded cells that are no longer close enough to be required. In the unload process, the data at grid[x][y] would be overwritten with the new data, which is created by looping through the objects in that cell and appending each new set of data to the grid cell data.
Everything works fine in terms of when you move in a direction, cells are unloaded/saved and new cells are loaded. The problem is this:
Say this is a large city infested by zombies. If you walk three grid squares in any direction and return, everything is as you left it. I'm struggling to find a way to at least simulate all objects still moving around and doing their thing. It looks silly when you for example throw a grenade, walk away, return and the grenade still hasn't detonated.
I've considered storing a timestamp on each object when I unload the level, and when it's initialized there's a loop that runs it's "step" function amount of times. Problem here is obviously that when you come back 5 minutes later, 20 zombies are going to try and step 248932489 times and the game will crash.
Ideas?
I don't know AS3 but let me try give you some tips.
It seems you want to make a seamless world since you load / unload cells as a player moves. That's a good idea. What you should do here is deciding what data a cell should load / unload( or, even further, what data a cell should hold or handle ).
For example, the grenade should not be unloaded by the cell as it needs to be updated even after the player leaves the cell. It's NOT a good idea for a cell to manage all game objects just because they are located in the cell. Instead, the player object could handle the grenade as an owner. Or, there could be one EntityManager which handles all game entities like grenades or zombies.
With this idea, you can update your 20 zombies even when they are in an unloaded zone (their location does not matter anymore) instead of calling update() 248932489 tiems at once. However, do you really need to keep updating the zombies? Perhaps, unloading all of them and spawning new zombies with the number of the latest active zombies in the cell would work. It depends on your game design but, usually, you don't have to update entities which are not visible or far enough from the player. Hope it helps. Good luck! :D
Interesting problem. Of course, game cannot simulate unlimited environment precisely. If you left some zone for a few minutes, you don't need every step of zombies (or any actors there) to be simulated precisely. Every game has its own simplications. Maybe approximate simulation will help you. For example, if survivor was in heavily infested zone for a long time, your simulator could decide that he turned into zombie, without computing every step of the process. Or, if horde was rampant in some part of the city, this part should be damaged randomly.
I see two methods as to how you could handle this issue.
first: you have the engine keep any active cells loaded, active means there are object-initiated events involving cell-owned objects OR player-owned objects (if you have made such a distinction that is). Each time such a cell is excluded from normal unloading behaviour it is assigned a number and if memory happens to run out the cells which have the lowest number will be unloaded. Clearly, this might be the hardest method code-wise but still it might be the only one truly doing what you desire.
second: use very tiny cells and let the engine keep a narrow path loaded. The cells migth then be 100x100 instead of 600x600 and 36 of them do the work one bigger cell would do ( risk: more cluttter code-wise) then each cell your player actually traverses ( not all that have been loaded to produce a natural visibility-range ) is kept in memory including every cell that has player-owned objects in it for a limited amount of time ( i.e. 5 minutes ).
I believe you can find out how to check for these conditions upon unloading yourself and hope to have been of help to you.

How do I amplify sounds by a specified number of decibels in AS3?

A few days ago, this was my question, and I found the answer. Maybe this will help someone else.
A. The first part of the problem: can you amplify sound using Flash? The AS3 documentation for SoundTransform says this about the volume attribute:
"The volume, ranging from 0 (silent) to 1 (full volume).
At face value, this means you can only make sounds quieter. In fact, if you supply a value greater than one (1.0), sounds will be amplified. You risk saturating the sound and getting poor quality, but you can do it, and for voice, you can get away with a lot. (Music is less forgiving, so experiment. This method does not do dynamic compression, which is better suited to music.)
B. The second part of the problem: the order in which you do things.
RIGHT:
soundTransform = new SoundTransform();
soundTransform.volume = volume * volumeAdjustment;
audioChannel.soundTransform = soundTransform;
WRONG:
soundTransform = new SoundTransform();
audioChannel.soundTransform = soundTransform;
soundTransform.volume = volume * volumeAdjustment;
I did some testing in CS3 and CS4, and got different results. In CS3, I could set the volume on the transform AFTER "audioChannel.soundTransform = soundTransform;" and everything was fine. But in CS4 it had no effect. I suspect that CS3 used pass by reference to set the soundTransform, while CS4 uses pass by value semantics and copies the object passed into it. The CS4 approach is better designed, but did break my code that worked fine in CS3.
C. The last question, is how to convert a decibel value to a factor that can be multiplied by the volume to amplify (or quiet) the sound by the desired amount.
var multiplier:Number = Math.pow(10, decibels / 20); // Power vs. amplitude
Note that "decibels" may be a positive number (to amplify) or a negative number (to make quieter). If decibels is zero, no change occurs.
A value for decibels of 3 will (to a close approximation) double the amplitude.
A value of 10 decibels will increase the volume tenfold (exactly).
Your decibel calculation should actually use 20, not 10:
var multiplier:Number = Math.pow(10, decibels / 20);
Digital audio is amplitude, not power (it's a representation of sound pressure, not sound power).