Audio format to choose for Big audio files - ios

Which audio file format is best to use for large audio files? I have many large audio files to be used in my app but their current mp3 size is of hundred of MB's

If you want to save more storage on audio files, file format may not change too much on the file size, reducing the bit rate(for example 320Kbps to 128Kbps) can reduce the file size significantly.

:how to do it using microsofts audio compression manager?(practically its not well documented in m.s.d.n.
Windows provide codecs that compress specifically audio files. The audio files tipically are PCM format (WAVE_FORMAT_PCM) and get played by using the simplest directsound method (check msdn it`s at hand and it works)
To play a file using directsound, thus PCM format you first create a directsound object, create a directsoundbuffer, and then pump the PCM data directly to the buffer using a keep-fill-buffer algorithm.
If you wish to use codecs, u try and write a procedure that opens a stream file and passes it through a acm driver object, thus (de)compressing it.
The driver for ACM (audio compression manager) finds a codecs that suits the input source and decompresses it yet again to WAVE_FORMAT_PCM for your app be able to play it.

Related

Transcoding fMP4 to HLS while writing on iOS using FFmpeg

TL;DR
I want to convert fMP4 fragments to TS segments (for HLS) as the fragments are being written using FFmpeg on an iOS device.
Why?
I'm trying to achieve live uploading on iOS while maintaining a seamless, HD copy locally.
What I've tried
Rolling AVAssetWriters where each writes for 8 seconds, then concatenating the MP4s together via FFmpeg.
What went wrong - There are blips in the audio and video at times. I've identified 3 reasons for this.
1) Priming frames for audio written by the AAC encoder creating gaps.
2) Since video frames are 33.33ms long, and audio frames 0.022ms long, it's possible for them to not line up at the end of a file.
3) The lack of frame accurate encoding present on Mac OS, but not available for iOS Details Here
FFmpeg muxing a large video only MP4 file with raw audio into TS segments. The work was based on the Kickflip SDK
What Went Wrong - Every once in a while an audio only file would get uploaded, with no video whatsoever. Never able to reproduce it in-house, but it was pretty upsetting to our users when they didn't record what they thought they did. There were also issues with accurate seeking on the final segments, almost like the TS segments were incorrectly time stamped.
What I'm thinking now
Apple was pushing fMP4 at WWDC this year (2016) and I hadn't looked into it much at all before that. Since an fMP4 file can be read, and played while it's being written, I thought that it would be possible for FFmpeg to transcode the file as it's being written as well, as long as we hold off sending the bytes to FFmpeg until each fragment within the file is finished.
However, I'm not familiar enough with the FFmpeg C API, I only used it briefly within attempt #2.
What I need from you
Is this a feasible solution? Is anybody familiar enough with fMP4 to know if I can actually accomplish this?
How will I know that AVFoundation has finished writing a fragment within the file so that I can pipe it into FFmpeg?
How can I take data from a file on disk, chunk at a time, pass it into FFmpeg and have it spit out TS segments?
Strictly speaking you don't need to transcode the fmp4 if it contains h264+aac, you just need to repackage the sample data as TS. (using ffmpeg -codec copy or gpac)
Wrt. alignment (1.2) I suppose this all depends on your encoder settings (frame rate, sample rate and GOP size). It is certainly possible to make sure that audio and video align exactly at fragment boundaries (see for example: this table). If you're targeting iOS, I would recommend using HLS protocol version 3 (or 4) allowing timing to be represented more accurately. This also allows you to stream audio and video separately (non-multiplexed).
I believe ffmpeg should be capable of pushing a live fmp4 stream (ie. using a long-running HTTP POST), but playout requires origin software to do something meaningful with it (ie. stream to HLS).

How to play mp3 content from resource in Delphi?

I have a TResourceStream contains a simple WAV sound.
I wrote that line into the resource.res file:
sound WAV "res\notify.wav"
I have the following method that works with WAV:
Res := TResourceStream.Create(HInstance, 'sound', 'WAV');
Res.Position := 0;
SndPlaySound(res.Memory, SND_MEMORY or SND_ASYNC);
Res.free;
I converted the WAV into MP3 and did the following things:
resource.res file: sound MP3 "res\notify.MP3"
Changed the play method first line to:
Res := TResourceStream.Create(HInstance, 'sound', 'MP3');
But nothing happens. It doesn't throw any exception, simple no sound heard.
How can I play MP3 as simple as WAV files?
The SndPlaySound API only supports waveform audio. It is not a general purpose multi-media API and as such does not (directly nor easily) support MP3 playback.
To play your audio through this API you would first need to decode the MP3 into the waveform format that the API expects.
(I should note that it appears to be possible to get the SndPlaySound API to play MP3 data by attaching a WAV header to the data. But detailed information about the audio is required in that header and the process is a decidely non-trivial exercise. It is almost certainly harder than using an API more suited to the task from the start.)
Your approach appears to be correct for obtaining a stream containing your MP3 data and with that data in memory there are a number of options available for playing that MP3 audio.
The BASS Audio Library is one such option though this is a commercial library and is not particularly cheap. It is however capable of exactly what you need.
There are numerous alternatives however, some cheaper, some even free which might also do the job though you may find it harder to get assistance with these if they are not as widely used or as well supported.
Even so, you might wish to review some of the alternatives listed on the torry.net directory. Specifically in the Components \ Effects and Multimedia section of the catalog.

FFmpeg save stream to mp3

I have an iOS project that play online radio streams, it is use FFmpeg to play. Also I added ability to record streams, decode streams via avcodec_decode_audio4 function, and write output to .wav file. But this files are too big, because it is uncompressed format, so I want to decode files to .mp3.
I have found couple ways to convert audio but only when audio it is ready file, but I want decode to some compressed format as soon as I get chunk of data from stream, not ready file.
Is it possible?
Can you give me some advise how to achieve this?
You can use ffmpeg (aka libav) to encode the audio you're reading with avcodec_decode_audio4 into a file as mp3, as long as libav was configured with lame (--enable-libmp3lame).
Basically, you configure an mp3 codec, then call avcodec_encode_audio2 (who names these things?) on the progressive output of avcodec_decode_audio4.
The canonical example can be confusing because it also deals with video, but you should be able to tease the details you want out of it.
This post on transcoding audio by arashafiei is broadly helpful.

Changing audio bit rate after recording

I'm recording audio files at a bit rate of 44.1khz. I like having high quality audio for playback purposes. However, when I want to export via text or email, the audio files fail to export because they're larger than 15MB (usually for audio files +3mins). Is there a way to reduce the bit rate only when I want to export? I've seen the following tutorial, but I'd rather keep my files as m4a rather than converting to aac:
http://atastypixel.com/blog/easy-aac-compressed-audio-conversion-on-ios/.
You can use AVAssetReader and AVAssetWriter to transcode an audio file to one with different parameters (lower bit rate, higher compression, etc.). Just because you create a new (temporary?) audio file for export doesn't force you to delete the current higher quality audio file you want for playback.

is it possible for avassetwriter to output to memory

I would like to write an iphone app that continuously capture video, h.264 encode them in 10 seconds interval and upload to a storage server. This can be done with avassetwriter, and I can keep on deleting the old files as I create new ones. However, as flash memory have a limited write cycles, this scheme will destroy the flash after a few thousand write cycles through the flash. Is there a way to redirect avassetwriter to memory, or create a ram drive on the iphone?
Thanks!
Yes avassetwriter is the only way to get to the hardware decoder. and simply reading back the file while its written doesn't give you the moov atoms so avfoundation or mpmediaplayer based players won't be able to read it back. you only have a couple choices , periodically stop the asassetwriter and write to the file on a background thread, effectively segmenting your movie into smaller complete files. or you could deal with the incomplete mp4 on the server side, you will have to decode the raw nalu's and recreate the missing moov atoms. If your using ffmpeg mov.c is source to look at. This is also were an incomplete mp4 file would fail.

Resources