Crop m4a on Android platform

Source: Internet
Author: User
Tags field table

The operation of setting the ringtone on the Android phone is more flexible, the general reader hears a favorite song, immediately can cut the song, cut to the clip, then through the system's interface set to the ringtone (telephone ringtone, alarm clock ringtone, etc.).

The premise is that the app that plays this song needs to provide the ability to crop the song.

So how do you implement the ability to intercept a fragment of an audio file?

It is natural to think of the use of the ffmpeg command to achieve, before the "Extract pictures from video" Content can be extracted fragments, such as:

Ffmpeg-ss 10-i audio.mp3-t 5 Out.mp3
The above command, starting from the 10th second, extracts 5 Seconds of fragments.

Readers can pay attention to "Guangzhou Xiao Cheng" public number and check the contents of "Audio Video->FFMPEG Structure & Application" menu item.

However, the FFmpeg command can be easily used on a PC, but it cannot be used directly on the mobile app.

The path here is for the Android platform to introduce another way to clip audio files, and, here, assume that the original audio file is in the M4A package format.

This article describes how to crop a m4a audio file on an Android platform and get an audio clip.

To achieve this function, there are two basic scenarios:

    • One is to decode the original audio file, then extract the corresponding fragment, and then encode the fragment.
    • The second is to directly locate the starting point of the crop, extract the fragments, and then save the new audio file.

In contrast, the first scenario has a more significant performance cost, but the scheme can take all the audio formats (as long as it can be decoded and eventually encoded in a fixed format).

The second scenario, which takes into account the implementation of different formats, including the original audio, as well as the format of the final audio, is superior in performance and is more time-saving than the first scenario.

The path introduces the implementation of the second scenario, and only considers the interception and generation of the M4A file.

The second scenario, in summary, is the parsing of the M4A format and the m4a file generation process .

(a) M4A introduction

M4A files, which are actually MP4 files, generally only store audio streams. M4A is the name of the Apple company, used to differentiate the generic MP4 file with video frames.

Parsing the M4A file format is parsing the MP4 file format, which is the same for writing files.

To intercept m4a fragments, it is necessary to parse the M4A file format to obtain relevant information (such as sample rate, number of channels, number of samples per frame, total frames, length of each frame, offset of each frame, etc.), and parsing the file format requires understanding the MP4 file format.

MP4 is made up of atom (or box), and all data (including various information and bare audio data) is placed in atom.

Each atom consists of three fields:

Len (the length of the Atom, 4Byte),
Type (Atom, 4Byte),
Data (Atom-saved).

Atom can be nested.

There are many types of atom, and not all types exist to form a valid MP4 file. But there are several types of atom that you must have:

Ftyp (identity file format),
Stts (number of samples per frame),
Stsz (length of each frame),
STSC (the relationship table between frames and chunk),
Mvhd (length and other information),
Mdat (bare data),
Moov and so on.

The specific structure, including the meaning of each atom, the size and meaning of each field, allows you to see the resources on the network (preferably the Atom's Field table).

Like what:


(ii) Programme implementation

The second solution can be implemented using ringdroid, an open source project.

Ringdroid is maintained on Git, and its latest version uses a decoding and recoding scheme.

Can get back ringdroid earlier version, there are CHEAPAAC, CheapMP3, respectively, the different formats of audio processing, and is directly intercepted.

CHEAPAAC ReadFile completes the parsing of the m4a file, WriteFile completes the writing of the new M4A file.

The CHEAPAAC also achieves the gain calculation, which can be used to display the waveform of the audio.

For interception, there are several messages that are important: {The length of the frame is the number of bytes}, the {frame offset}, which can be intercepted based on these two sets.

The length of the frame (and the total number of frames) is determined when parsing the Stsz, and the offset of the frame is determined when parsing the mdat.

Readers can read the CHEAPAAC code in detail to understand the interception process. Xiao Cheng here only to mention the problem of CHEAPAAC, but also the reader may encounter problems.

(1) Incompatible NEROAACENC encoded M4A file

For the M4A file encoded by Neroaacenc, CHEAPAAC cannot parse the bare data normally at Parsemdat, because Neroaacenc adds 8 bytes to the bare data before the 8 bytes make the offset of each frame calculated is incorrect. The data for each frame that was written at the time of the subsequent WriteFile is incorrect.

Consider skipping 8 bytes to solve this problem (when judging the M4A encoded by Nero):

        if (Mmdatoffset > 0 && mmdatlength > 0) {final int neroaacfrom = 570;            int neroskip = 0;                if (Mmdatoffset-neroaacfrom > 0) {fileinputstream cs = new FileInputStream (minputfile);                Cs.skip (Mmdatoffset-neroaacfrom);                Final int flagsize = 14;                byte[] buffer = new Byte[flagsize];                Cs.read (buffer, 0, flagsize); if (buffer[0] = = ' N ' && buffer[1] = = ' E ' && buffer[2] = = ' R ' && buffer[3] = = ' O ' && buffer [5] = = ' A ' && buffer[6] = = ' A ' && buffer[7] = = ' C ' && buffer[9] = = ' C ' &amp ;& buffer[10] = = ' O ' && buffer[11] = = ' d ' && buffer[12] = = ' E ' && buffe                R[13] = = ' C ') {Neroskip = 8;            } cs.close ();            } stream = new FileInputStream (minputfile); MmdatoffsET + = Neroskip;            Slip 8 Bytes If need Stream.skip (Mmdatoffset);            Moffset = Mmdatoffset;        Parsemdat (stream, mmdatlength);        } else {throw new java.io.IOException ("didn ' t find Mdat"); }
(2) The length of the Intercept fragment is incorrect

The length of the truncated fragment is not reset and the length of the original file is still used.

You can reset the length of the clip inside the WriteFile, but be aware that if you end up using MediaPlayer to play, you cannot code because the MediaPlayer decoding is inconsistent with ffmpeg. If you end up with ffmpeg and so on to decode, you need to reset the duration of the clip.

        After writing the Stco, add: Long time = System.currenttimemillis ()/1000;  Time + = (66 * 365 + 16) * 24 * 60 * 60;        Number of seconds between 1904 and 1970 byte[] Createtime = new Byte[4];        Createtime[0] = (byte) ((Time >>) & 0xFF);        CREATETIME[1] = (byte) ((Time >>) & 0xFF);        CREATETIME[2] = (byte) ((Time >> 8) & 0xFF);        CREATETIME[3] = (byte) (Time & 0xFF);        Long NumSamples = 1024x768 * numframes;        Long DurationMS = (NumSamples * +)/msamplerate;            if ((NumSamples *)% Msamplerate > 0) {//round the duration up.        durationms++; } byte[] numsaplesbytes = new byte[] {(byte) ((NumSamples >>) & 0XFF), ( BYTE) ((NumSamples >>) & 0XFF), (Byte) ((NumSamples >> 8) & 0XFF), (byt        e) (NumSamples & 0XFF)};                byte[] durationmsbytes = new byte[] {(byte) ((DurationMS >>) & 0XFF), (Byte) ((DurationMS >> +) & 0XFF), (byte) ((        DURATIONMS >> 8) & 0XFF), (Byte) (DurationMS & 0XFF)};        int type = KMDHD;        Atom Atom = Matommap.get (type);            if (atom = = null) {atom = new atom ();        Matommap.put (type, atom); } atom.data = new byte[] {0,//version, 0 or 1 0, 0, 0,//flag CRE                Atetime[0], createtime[1], createtime[2], createtime[3],//creation time.                Createtime[0], createtime[1], createtime[2], createtime[3],//modification time.  0, 0, 0x03, (byte) 0xe8,//timescale = $ = Duration expressed in Ms.                 1000 for units durationmsbytes[0], durationmsbytes[1], durationmsbytes[2], durationmsbytes[3],//duration in Ms.        0, 0,//languages 0, 0//pre-defined;        }; Atom.len = Atom.data.length + 8;        Type = KMVHD;        Atom = Matommap.get (type);            if (atom = = null) {atom = new atom ();        Matommap.put (type, atom); } atom.data = new byte[] {0,//version, 0 or 1 0, 0, 0,//flag Crea                Tetime[0], createtime[1], createtime[2], createtime[3],//creation time.                Createtime[0], createtime[1], createtime[2], createtime[3],//modification time.  0, 0, 0x03, (byte) 0xe8,//timescale = $ = Duration expressed in Ms.                 1000 for units durationmsbytes[0], durationmsbytes[1], durationmsbytes[2], durationmsbytes[3],//duration in Ms. 0, 1, 0, 0,//rate = 1.0 1, 0,//volume = 1.0 0, 0,//Rese RVed 0, 0, 0, 0,//reserved 0, 0, 0, 0,//reserved 0, 1, 0, 0, 0, 0, 0, 0                , 0, 0, 0, 0,//Unity matrix for video, 36bytes0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0,//P re-defined 0, 0, 0, 0,//pre-defined 0, 0, 0, 0,//pre-defined 0, 0, 0, 0 ,//pre-defined 0, 0, 0, 0,//pre-defined 0, 0, 0, 0,//pre-defined 0,        0, 0, 2//Next track ID, 4bytes}; Atom.len = atom.data.length + 8;
(iii) Other concepts

There are some audio concepts involved in the CHEAPAAC, and a simple explanation for the short range. Readers can also pay attention to "Guangzhou Xiao Cheng" public number, check the "Audio and Video" menu under the article.

Track, i.e. tracks (audio or video), also called streams;
Sample, understood as the frame (unlike the concept of the sample), for AAC, a frame includes a fixed number of samples, are 1024;
Chunk, or block, is a collection of frames.

NEROACC Command Use Example:

Ffmpeg-i "1.mp3"-F wav-| NEROAACENC-BR 32000-ignorelength-if--of "1.m4a"
-BR Code Rate
-lc/-he/-hev2 encoding method, default is he
-if input File
-of output File
-ignorelength used with other outputs (such as ffmpeg) as input

At this point, the implementation of crop M4A on the Android platform is complete.

To summarize, this article describes the implementation of using CHEAPAAC to crop m4a to get the fragment file on the Android platform, and also introduces the concept of M4A structure and the problems that may be encountered.

Crop m4a on Android platform

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.