Titanium Extracting first 10 secs of audio from Ti.MediaSound Object - iphone

I need to extract first Ten(10) secs from an audio file.
We have the following code.
var file = recording.stop();
sound = Titanium.Media.createSound({sound:file});
I need to extract first 10 seconds from sound object.
How we can do this?
Also, How to merge two sound objects.
ex:
sound1 has 10 secs and sound2 has 15secs.
I want sound3 which is sound1 + sound2,
which should play both sound1 and sound2 continuously.
Thanks in Advance.

var sound = Ti.Media.createSound({
sound: file,
duration: 10
});
That will get you the first 10 seconds of the sound however even with the looping set to true you will need to create your own custom timers to alternate between the sounds playing.

Related

How to skip ahead n seconds while playing track using web audio API?

Using Web Audio API, I'm trying to build an mp3 player with a "Skip ahead 15 seconds" feature.
I'm able to load an mp3 using a source buffer, and can get it to start playing. I want to do something like this, though I know currentTime is not a settable property:
context.currentTime += 15
How do you skip forward n seconds once the song is already playing?
Unfortunately there is no single API call to achieve the desired effect but it's doable. Every AudioBufferSourceNode can only be used once which is why we have to create a new one in order to change something.
Let's imagine we have two variables coming from somewhere called audioContext and audioBuffer. In addition we define two more variables to store the initial startTime and the currently running AudioBufferSourceNode.
let audioBufferSourceNode;
let startTime;
The first time we play the audioBuffer we play it directly from the start. The only special thing here is that we keep a reference to the audioBufferSourceNode and that we remember the startTime.
audioBufferSourceNode = audioContext.createBufferSource();
audioBufferSourceNode.buffer = audioBuffer;
audioBufferSourceNode.connect(audioContext.destination);
startTime = context.currentTime;
audioBufferSourceNode.start(startTime);
If you want to skip ahead some time later the previously started audioBufferSourceNode needs to be stopped first.
const currentTime = context.currentTime;
audioBufferSourceNode.stop(currentTime);
audioBufferSourceNode.disconnect();
In addition a new one needs to be created by reusing the same audioBuffer as before. The only difference here is that we apply an offset to make sure it skips 15 seconds ahead.
audioBufferSourceNode = audioContext.createBufferSource();
audioBufferSourceNode.buffer = audioBuffer;
audioBufferSourceNode.connect(audioContext.destination);
audioBufferSourceNode.start(currentTime, currentTime - startTime + 15);
To be prepared to skip another time it's necessary to update the startTime.
startTime -= 15;
This is of course an oversimplified example. In reality there should be a check to make sure that there is enough audio data left to skip ahead. You could also apply a little fade-in/out when skipping to avoid click sounds. ... This is only meant to illustrate the general idea.

HTML5 Audio: Setting currentTime and then playing on iPhone spontaneously rewinds 50-100 milliseconds

I'm attempting to play audio from a specific location inside a file while also receiving updates on the playback using the onTimeUpdate event. I examine the currentTime property within the onTimeUpdate handler so that I can provide visual feedback on where we are in the file.
My problem is that when I set currentTime to a known value and then call play(), the first time I get the currentTime property in my onTimeUpdate handler, it will be as I set it. But the next time onTimeUpdate is called, it's actually a smaller value than I originally started playing from, sometimes more than 100 ms smaller!
For example:
player.currentTime = 2.0;
player.play();
Then, outputting player.currentTime from within my onTimeUpdate handler:
2
1.95 // WTF??
2.24
2.56
...
The problem is that this causes my UI widgets that indicate the current location in the track to jump around. I have a clunky workaround that I am implementing, but I'd like to know if there is any known way to stop this from happening, or if I'm just not doing something right.
To my knowledge, it only happens on iPhone. I'm testing with an iPhone 6 and iOS 10.1.1.
Here's a demonstration if you'd like to see this for yourself.
http://codepen.io/brianrak/pen/7db413c4431827fe3318e99ae497cf2a?editors=1010
Thanks in advance!
var second = ("0" + parseInt(player.currentTime % 60)).slice(-2);
var minutes = ("0" + parseInt((player.currentTime / 60) % 60)).slice(-2);

Synchronize the playback of two or more AVAudioPlayer in Iphone

I need to play 2 sounds with 2 AVAudioPlayer objects at the same exact time... so I found this example on Apple AVAudioPlayer Class Reference (https://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html):
- (void) startSynchronizedPlayback {
NSTimeInterval shortStartDelay = 0.01; // seconds
NSTimeInterval now = player.deviceCurrentTime;
[player playAtTime: now + shortStartDelay];
[secondPlayer playAtTime: now + shortStartDelay];
// Here, update state and user interface for each player, as appropriate
}
What I don't understand is: why also the secondPlayer has the shorStartDelay?
Shouldn't it be without? I thought the first Player needed a 0.1 sec delay as it is called before the second Player... but in this code the 2 players have the delay...
Anyone can explain me if that is right and why?
Thanks a lot
Massy
If you only use the play method ([firstPlayer play];), firstPlayer will start before the second one as it will receive the call before.
If you set no delay ([firstPlayer playAtTime:now];), the firstPlayer will also start before de second one because firstPlayer will check the time at which it is supposed to start, and will see that it's already passed. Thus, it will have the same behaviour as when you use only the play method.
The delay is here to ensure that the two players start at the same time. It is supposed to be long enough to ensure that the two players receive the call before the 'now+delay' time has passed.
I don't know if I'm clear (English is not my native langage). I can try to be more clear if you have questions
Yeah what he said ^ The play at time will schedule both players to start at that time (sometime in the future).
To make it obvious, you can set "shortStartDelay" to 2 seconds and you will see there will be a two second pause before both items start playing.
Another tip to keep in mind here are that when you play/pause AVAudioPlayer they dont actually STOP at exactly the same time. So when you want to resume, you should also sync the audio tracks.
Swift example:
let currentDeviceTime = firstPlayer.deviceCurrentTime
let trackTime = firstPlayer.currentTime
players.forEach {
$0.currentTime = trackTime
$0.play(atTime: currentDeviceTime + 0.1)
}
Where players is a list of AVAudioPlayers and firstPlayer is the first item in the array.
Notice how I am also resetting the "currentTime" which is how many seconds into the audio track you want to keep playing. Otherwise every time the user plays/pauses the track they drift out of sync!

AVPlayer seektoTime iPhone

I have used seekToTime in my application and its working properly. But I want to have some more information about it. Which is, if I have a streaming video file of 1 minute now I want to play it from second 15th to second 45 (first 15 seconds and the last 15 seconds will not play).
How can I do it?
I know that by use of seekToTime I can play a video from 15th second but how to stop it at 45th second and also get noticed by the method that the video has played for the specified time period?
CMTime timer = CMTimeMake(15, 1);
[player seekToTime:timer];
The above code takes me to the 15th second of the streaming file but how to stop it on 45th second and get notified too?
I have searched a lot but couldn't get any info.
Thanks
EDIT:
As #codeghost suggested, simply use forwardPlaybackEndTime.
You can simply use:
yourAVPlayerItem.forwardPlaybackEndTime = CMTimeMake(10, 1);
Here 10 is the time till the AVPlayerItem will play.
Set the forwardPlaybackEndTime property on your AVPlayerItem.
I don't know if there is something build-in for this in AVPlayer, but what i would do is build an function and call it with :
[self performSelector:#selector(stopPlaying) withObject:nil afterDelay:45];
-(void)stopPlaying{
[player pause];
}
this will stop playing after 45 seconds,and of course you can put instead 45 any number of seconds that you want.
You can use [AVPlayer addPeriodicTimeObserverForInterval:queue:usingBlock:] for that purpose.
Get the AVPlayer.currentTime periodically, and call pause or stop on the exact time.

Loop duration of rec, av foundation framework

I'm using the av foundation framework to record video.
I've set a max duration of 10 sec for the video output.
Is it possible to loop the recording over the 10 sec interval instead of stop the recording.
My goal is to only store the 10 most recent sec of the video output.
Thanks!
In your case, you wouldn't like to stop the record because you can never know when the user will eventually stop it, then your only option is to save the whole thing and trim it after the user clicked the stop button.
To trim a video, try using the videoMaximumDuration of UIVideoEditorController
See an example of UIVideoEditorController here:
http://iphone-book-sample.googlecode.com/svn/trunk/Chapter12/UIVideoEditorControllerSample/