IOS study notes 23-sound effects and music
I. Audio
In iOS, audio playback can be divided into audio playback and music playback.
* Sound effects:
* It mainly refers to the playback of some short audios, which generally do not require progress or loop control.
* In iOS, we use sound effects.AudioToolbox.framework
Framework implementation.
* Music:
* It mainly refers to some long audios and usually requires precise control over playback.
* In iOS, we use music.AVFoundation.framework
Framework implementation.
Ii. Sound Effects
AudioToolbox.framework
The framework is a set of C language-based frameworks.
Its implementation principle is:Register Short audio to SystemSoundService)
Some restrictions on the system sound service: the audio playback time cannot exceed 30 s. The data must be in PCM or IMA4 format. Currently, all audio files must be in the CAF, AIF, and WAV formats, in fact, some MP3 formats can also be played. Procedure: Import
AudioToolbox.framework
Framework, add the header file:
#import
Obtain the path URL of the audio file and add it to the system sound service to obtain the system sound ID, which is the unique identifier for distinguishing different sound effects.
Void AudioServicesCreateSystemSoundID (CFURLRef inFileURL,/* Audio File URL, You need to bridge NSURL to CGURLRef */SystemSoundID * outSystemSoundID/* return the unique sound ID */);
If you want to listen for audio playback, You need to bind a callback function.
Void AudioServicesAddSystemSoundCompletion (SystemSoundID inSystemSoundID,/* Sound ID */CFRunLoopRef inRunLoop,/* loop, usually NULL */CFStringRef inRunLoopMode,/* loop mode, it is generally NULL */void (*) (SystemSoundID, void *) inCompletionRoutine,/* callback C function pointer */void * inClientData/* callback function parameter */);
Start playback. There are two Playback modes:
/* Start Playing sound effects */void AudioServicesPlaySystemSound (SystemSoundID inSystemSoundID);/* Start Playing Sound Effects and vibrate */void AudioServicesPlayAlertSound (SystemSoundID inSystemSoundID );
The following is an example:
-(Void) viewDidLoad {[super viewDidLoad]; [self playSoundEffect: @ "bellTone.wav"] ;}# pragma mark-callback function for audio/* playback completion, this is a C function. The first parameter is the sound effect ID, and the second parameter is the omnipotent parameter */void soundCompleteCallBack (SystemSoundID soundID, void * clientData) {NSLog (@ "" ");} -(void) playSoundEffect :( NSString *) name {// obtain the audio file path NSString * filePath = [[NSBundle mainBundle] pathForResource: name ofType: nil]; // create a sound file url nsurl * fileUrl = [NSURL URLWithString: filePath]; // the unique sound ID SystemSoundID soundID = 0; // Add the sound effect to the system sound service. NSURL needs to be converted to CFURLRef, and a long integer ID will be returned, which uniquely identifies the sound effect with AudioServicesCreateSystemSoundID (_ bridge CFURLRef) (fileUrl), & soundID); // sets the callback C language function AudioServicesAddSystemSoundCompletion (soundID, NULL, NULL, soundCompleteCallBack, NULL) after the sound is played ); // start playing the audio effect AudioServicesPlaySystemSound (soundID );}
Iii. Music
If you want to play a large audio, You need to precisely control it. We need to use another framework, that is:
AVFoundation.framework
Framework, which supports multiple audio formats and can be precisely controlled.
Which of the following functions is used for playing music?AVFoundation.framework
OfAVAudioPlayer
Music player.
Below are some
AVAudioPlayer
Common attributes of a class:
@ Property (readonly, getter = isPlaying) BOOL playing; // whether the video is being played @ property NSTimeInterval currentTime; // The current playback time @ property (readonly) NSTimeInterval duration; // The total playback time @ property float volume; // volume size @ property float rate; // The playback rate. The default value is 1.0 @ property (readonly) NSURL * url; // URL of the music file
The following are common object methods:
/* Initialization Method */-(instancetype) initWithContentsOfURL :( NSURL *) url error :( NSError **) outError;-(BOOL) prepareToPlay; /* load the music file to the cache */-(BOOL) play;/* start playing music */-(BOOL) playAtTime :( NSTimeInterval) time; /* start playing the music at the specified time */-(void) pause;/* interrupt the music, you can call the play method to continue playing */-(void) stop; /* Stop the music and cannot play it again */
Common proxy methods:
/* Call at playback completion */-(void) audioPlayerDidFinishPlaying :( AVAudioPlayer *) player successfully :( BOOL) flag;/* call at audio decoding error */-(void) audioPlayerDecodeErrorDidOccur :( AVAudioPlayer *) player error :( NSError *) error;
Procedure: Import
AVFoundation.framework
Framework, add the header file:
#import
Obtain the URL of the local file of a music file. You cannot use a web URL to create a music player object.
AVAudioPlayer
And set properties and proxies. Call
perpareToPlay
Method to load the music file to the buffer
play
Method playback, call
pause
Interrupted playback
AVAudioPlayerDelegate
Method to complete the listener playback. Let's make a simple music player: You can play music cyclically, interrupt music, switch between different music, and know the playback progress. The following is the specific simple music player project code:
# Import "ViewController. h "# import @ interface ViewController () @ property (nonatomic, strong) NSArray * musicArray;/* <music list */@ property (nonatomic, strong) IBOutlet UIProgressView * progress; /* <progress bar */@ property (nonatomic, strong) AVAudioPlayer * audioPlayer;/* <music player object */@ property (nonatomic, strong) NSTimer * timer; /* timer */@ property (nonatomic, strong) IBOutlet UILabel * titleLabel;/* display title */@ property (Nonatomic, assign) NSInteger selectMusic;/* index of the currently played music */@ end @ implementation ViewController-(void) viewDidLoad {[super viewDidLoad]; // list of music files self. musicArray = @ [@ "great dreamer", @ "Jiangnan", @ "Wine jerky", @ "bubble", @ "Charlotte troubles", @ "Actor"]; // create a timer to continuously update the progress bar self. timer = [NSTimer scheduledTimerWithTimeInterval: 0.5 target: self selector: @ selector (updataProgress) userInfo: nil repeats: YES]; // create a player [self initAudioPlayerWithNumber: 0]; // The Player starts playing the music [self. audioPlayer play];}/* initialize the player */-(void) initAudioPlayerWithNumber :( NSInteger) num {if (num> = self. musicArray. count) {return;} // obtain the music file path NSString * name = self. musicArray [num]; NSString * filePath = [[NSBundle mainBundle] pathForResource: name ofType: @ "mp3"]; // create a music file URL, which must be fileURLWithPath, AVAudioPlayer does not support http url nsurl * fileUrl = [NSURL fileURLWithPath: filePath]; // create a player NSErr Or * error = nil; AVAudioPlayer * audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: fileUrl error: & error]; if (error) {NSLog (@ "error of player initialization, error: % @ ", error. localizedDescription); return;} audioPlayer. numberOfLoops = 0; // set the number of cycles. 0 indicates that the audioPlayer is not cyclic. delegate = self; // sets the proxy [audioPlayer prepareToPlay]; // loads the music file to the cache and does not play self. selectMusic = num; // Save the current music index self. audioPlayer = audioPlayer; // Save the current player self. ti TleLabel. text = name; // set the title}/* progress bar update method, updated every 0.5 seconds */-(void) updataProgress {// currentTime is the current playback time, duration is the total playback duration CGFloat progress = self. audioPlayer. currentTime/self. audioPlayer. duration; [self. progress setProgress: progress animated: YES];}/* click the play button */-(IBAction) musicPlay :( id) sender {// if the player is not playing, you need to call the playback method if (! [Self. audioPlayer isPlaying]) {[self. audioPlayer play]; // restores the timer self. timer. fireDate = [NSDate distantPast] ;}}/* click the pause button */-(IBAction) musicPause :( id) sender {// if the player is playing, to call the suspend method if ([self. audioPlayer isPlaying]) {[self. audioPlayer pause]; // stop the timer self. timer. fireDate = [NSDate distantFuture];}/* click the next song button */-(IBAction) next :( id) sender {// The Music index increases progressively by self. selectMusic = (self. selectMusic + 1) % self. musicArray. count; // reset the player [self initAudioPlayerWithNumber: self. selectMusic]; // player playback [self. audioPlayer play] ;}# pragma mark-AVAudioPlayerDelegate proxy method-(void) Quit :( AVAudioPlayer *) player successfully :( BOOL) flag {// automatically redirects to play the next song [self next: nil];}
B is also simple enough. You can make a little more elegant. For example, if each song corresponds to an image, when you cut the song, the picture will be displayed in the background, it must be more pleasing to the eye, O (∩ _ ∩) O ~, I have not found any good images. <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4NCjxoMyBpZD0 = "four-Background Music"> 4. Background Music
In fact, there is a problem with the player above, that is, once we enter the background, our music player will be suspended automatically, and we cannot/(ㄒ o workshop )/~~! What should we do?
1. Set the background Running Mode
Set the info. plist file and add fieldsRequired background modes
,
And setApp plays audio or streams audio/video using AirPlay
2. Use audio sessions to set the background running type
// Obtain the audio session singleton object AVAudioSession * audioSession = [AVAudioSession sharedInstance]; // set the session to play in the background [audioSession setCategory: AVAudioSessionCategoryPlayback error: NULL]; // activate the modification, start the session [audioSession setActive: YES error: NULL];
In addition to background playback, audio sessions can also play in the following modes:
The above Code only needs to modify the initialization method of the player to implement background playback:
/* Initialize the player */-(void) initAudioPlayerWithNumber :( NSInteger) num {if (num> = self. musicArray. count) {return;} // obtain the music file path NSString * name = self. musicArray [num]; NSString * filePath = [[NSBundle mainBundle] pathForResource: name ofType: @ "mp3"]; // create a music file URL, which must be fileURLWithPath, AVAudioPlayer does not support http url nsurl * fileUrl = [NSURL fileURLWithPath: filePath]; // creates a player NSError * error = nil; AVAudioPlayer * audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: fileUrl error: & error]; if (error) {NSLog (@ "Player initialization error, error: % @", error. localizedDescription); return;} audioPlayer. numberOfLoops = 0; // set the number of cycles. 0 indicates that the audioPlayer is not cyclic. delegate = self; // sets the proxy [audioPlayer prepareToPlay]; // loads the music file to the cache, it will not play yet // obtain the audio session singleton object AVAudioSession * audioSession = [AVAudioSession sharedInstance]; // set the session to play in the background [audioSession setCategory: AVAudioSessionCategoryPlayback error: NULL]; // activate the modification and start the session [audioSession setActive: YES error: NULL]; self. selectMusic = num; // Save the current music index self. audioPlayer = audioPlayer; // Save the current player self. titleLabel. text = name; // set the title}