How get metadata of video in Blackberry 10 Cascade? - metadata

I have C++ Blackberry Cascade application. I'm trying to read metadata of video file using this code
onMetaDataChanged: {
console.log("player onMetaDataChanged");
console.log("--------------------------------bit_rate=" + myPlayer.metaData.bit_rate);
console.log("-----------------------------------genre=" + myPlayer.metaData.genre);
console.log("-----------------------------sample_rate=" + myPlayer.metaData.sample_rate);
console.log("-----------------------------------title=" + myPlayer.metaData.title); }
But this only works after the video file is played. Is there any way to get metadata of video file, without playing it? Thanks.

Call prepare slot. It will acquire resources necessary for playback without playing the track and emit MetaDataChanged signal.
myPlayer.prepare()

Related

Get the duration of .m3u audio

I want to play audio by the URL
https://wortcast01.wortfm.org/appfiles/wort_210715_080006buzzthu.m3u
it has a body(with tracks)
https://wortcast01.wortfm.org/pitch/preroll-buzzthu.mp3
https://wortcast01.wortfm.org/mp3/wort_210715_080006buzzthu.mp3
When I set https://wortcast01.wortfm.org/appfiles/wort_210715_080006buzzthu.m3u to the AVPlayer then the duration is equal to Nan. But each track from the list has a duration.
Do you have an idea how to extract duration via AVPlayer?
return Nan:
var itemDuration: Double? {
return currentItem?.duration.seconds
}
AVFoundation(AVPlayer, AVAsset....) automatically marks any .m3u like "Live broadcasting" (my assumption: It looks like Apple uses scenario M3U8 for working with M3U)
Solution:
Create additional functionality which loads m3u(or pls) content, create an internal playlist, and play these internal parts ar AVPlayer.

Synchronizing Playback of Multiple Audio Files in Audio Kit

I am developing a small audio sequencer application using AudioKit. I only need to play back 4 channels of audio. However I need to play them back perfectly synchronized down to the sample level. When I run a test using just two audio files, I can hear that they are not synchronized. The difference is only a few samples, but even a one sample discrepancy would be a problem. I am currently using multiple AKClipPlayer objects routed to an AKMixer object. I called him with the basics for loop like this:
private var clipPlayers : [AKClipPlayer] = []
func play(){
for player in clipPlayers{
player.play()
}
}
Is sample accurate playback timing of multiple audio files possible using AudioKit?
Yes, you need to schedule playback to start in the future with play(at:).
// This can take longer than expected, so do this before choosing a future time
clipPlayers.forEach { $0.prepare(withFrameCount: 10_000) }
let nearFuture = AVAudioTime.now() + 0.2
clipPlayers.forEach { $0.play(at: nearFuture) }

SWIFT - Is it possible to save audio from AVAudioEngine, or from AudioPlayerNode? If yes, how?

I've been looking around Swift documentation to save an audio output from AVAudioEngine but I couldn't find any useful tip.
Any suggestion?
Solution
I found a way around thanks to matt's answer.
Here a sample code of how to save an audio after passing it through an AVAudioEngine (i think that technically it's before)
newAudio = AVAudioFile(forWriting: newAudio.url, settings: nil, error: NSErrorPointer())
//Your new file on which you want to save some changed audio, and prepared to be bufferd in some new data...
var audioPlayerNode = AVAudioPlayerNode() //or your Time pitch unit if pitch changed
//Now install a Tap on the output bus to "record" the transformed file on a our newAudio file.
audioPlayerNode.installTapOnBus(0, bufferSize: (AVAudioFrameCount(audioPlayer.duration)), format: opffb){
(buffer: AVAudioPCMBuffer!, time: AVAudioTime!) in
if (self.newAudio.length) < (self.audioFile.length){//Let us know when to stop saving the file, otherwise saving infinitely
self.newAudio.writeFromBuffer(buffer, error: NSErrorPointer())//let's write the buffer result into our file
}else{
audioPlayerNode.removeTapOnBus(0)//if we dont remove it, will keep on tapping infinitely
println("Did you like it? Please, vote up for my question")
}
}
Hope this helps !
One issue to solve:
Sometimes, your outputNode is shorter than the input: if you accelerate the time rate by 2, your audio will be 2 times shorter. This is the issue im facing for now since my condition for saving the file is (line 10)
if(newAudio.length) < (self.audioFile.length)//audiofile being the original(long) audio and newAudio being the new changed (shorter) audio.
Any help here?
Yes, it's quite easy. You simply put a tap on a node and save the buffer into a file.
Unfortunately this means you have to play through the node. I was hoping that AVAudioEngine would let me process one sound file into another directly, but apparently that's impossible - you have to play and process in real time.
Offline rendering Worked for me using GenericOutput AudioUnit. Please check this link, I have done mixing two,three audios offline and combine it to a single file. Not the same scenario but it may help you for getting some idea. core audio offline rendering GenericOutput

AVAudioPlayer returns error "pty?"

AVAudioPlayer seems not to handle some audio files that can be handled if using AudioStreamer (https://github.com/mattgallagher/AudioStreamer) even when played as a local file.
My questions:
1) What type of audio files generate the error code "pty?". NOTE: Audio file plays fine in QuickTime Player.
2) The following code generates the same error using this audio file:
UInt32 size;
OSStatus err = AudioFileGetPropertyInfo([self audioFileID], kAudioFilePropertyChannelLayout, &size, NULL);
But using the stream api on the same audio file this will work (ok different properties are fetched but then the question is why can't channel layout be asked?):
err = AudioFileStreamGetPropertyInfo(inAudioFileStream, kAudioFileStreamProperty_FormatList, &formatListSize, &outWriteable);
I know that if you stream audio you need to use the stream api because only a part of the file is available at the time. But when the complete file is in the filesystem the file audio api should be possible to use (?)
3) Is it recommended to use stream api even if the file is local? Good ideas how to implement it are welcome.
What puzzles me is why AudioFile* api fails were AudioFileStream* works.

Realtime AudioQueue Record-Playback

Hey fellows,
Iam trying to build an application for realtime voicechanging.
In a first step I managed to record audiodata to a specified file and to play it after recording.
Now I try to change the code for playing back the audiobuffers right after recording them in loop.
My question is, how it is possible to read the Audiodata directly from the recording Audioqueue and not (like shown in documentation) from a file.
Iam thankful for any ideas and could show code-parts if needed.
Thanks in advance,
Lukas (from Germany)
Have a look at the SpeakHere example. This line sources the audio data:
OSStatus result = AudioFileReadPackets(THIS->GetAudioFileID(), false, &numBytes, inCompleteAQBuffer->mPacketDescriptions, THIS->GetCurrentPacket(), &nPackets,
inCompleteAQBuffer->mAudioData);
So, rather than call AudioFileReadPackets, you can just use a memcpy to copy over the recorded data buffer. Or, alternatively, supply to the playback AudioQueue a pointer to the audio data buffer. As playback continues, advance a mCurrentPacket pointer through the buffer.
To record, you'll do something very similar. Rather than writing out to a file, you'll write out to a buffer in memory. You'll first need to allocate that with a malloc. Then are your incoming AudioQueue captures recorded data, you copy that data to the buffer. As more data is copied, you advance the recording head, or mCurrentPacket to a new position.