18
18
static NSString *const kIdentity = @" alice" ;
19
19
static NSString *const kTwimlParamTo = @" to" ;
20
20
21
- @interface ViewController () <PKPushRegistryDelegate, TVONotificationDelegate, TVOCallDelegate, CXProviderDelegate , UITextFieldDelegate>
21
+ @interface ViewController () <PKPushRegistryDelegate, TVONotificationDelegate, TVOCallDelegate, CXProviderDelegate , UITextFieldDelegate, AVAudioPlayerDelegate >
22
22
23
23
@property (nonatomic , strong ) NSString *deviceTokenString;
24
24
@@ -45,6 +45,9 @@ @interface ViewController () <PKPushRegistryDelegate, TVONotificationDelegate, T
45
45
@property (weak , nonatomic ) IBOutlet UISwitch *muteSwitch;
46
46
@property (weak , nonatomic ) IBOutlet UISwitch *speakerSwitch;
47
47
48
+ @property (nonatomic , assign ) BOOL playCustomRingback;
49
+ @property (nonatomic , strong ) AVAudioPlayer *ringtonePlayer;
50
+
48
51
@end
49
52
50
53
@implementation ViewController
@@ -71,6 +74,14 @@ - (void)viewDidLoad {
71
74
72
75
self.activeCallInvites = [NSMutableDictionary dictionary ];
73
76
self.activeCalls = [NSMutableDictionary dictionary ];
77
+
78
+ /*
79
+ Custom ringback will be played when this flag is enabled.
80
+ When [answerOnBridge](https://www.twilio.com/docs/voice/twiml/dial#answeronbridge) is enabled in
81
+ the <Dial> TwiML verb, the caller will not hear the ringback while the call is ringing and awaiting
82
+ to be accepted on the callee's side. Configure this flag based on the TwiML application.
83
+ */
84
+ self.playCustomRingback = NO ;
74
85
}
75
86
76
87
- (void )configureCallKit {
@@ -361,11 +372,25 @@ - (void)cancelledCallInviteReceived:(TVOCancelledCallInvite *)cancelledCallInvit
361
372
- (void )callDidStartRinging : (TVOCall *)call {
362
373
NSLog (@" callDidStartRinging:" );
363
374
375
+ /*
376
+ When [answerOnBridge](https://www.twilio.com/docs/voice/twiml/dial#answeronbridge) is enabled in the
377
+ <Dial> TwiML verb, the caller will not hear the ringback while the call is ringing and awaiting to be
378
+ accepted on the callee's side. The application can use the `AVAudioPlayer` to play custom audio files
379
+ between the `[TVOCallDelegate callDidStartRinging:]` and the `[TVOCallDelegate callDidConnect:]` callbacks.
380
+ */
381
+ if (self.playCustomRingback ) {
382
+ [self playRingback ];
383
+ }
384
+
364
385
[self .placeCallButton setTitle: @" Ringing" forState: UIControlStateNormal];
365
386
}
366
387
367
388
- (void )callDidConnect : (TVOCall *)call {
368
389
NSLog (@" callDidConnect:" );
390
+
391
+ if (self.playCustomRingback ) {
392
+ [self stopRingback ];
393
+ }
369
394
370
395
self.callKitCompletionCallback (YES );
371
396
@@ -425,6 +450,10 @@ - (void)callDisconnected:(TVOCall *)call {
425
450
426
451
self.userInitiatedDisconnect = NO ;
427
452
453
+ if (self.playCustomRingback ) {
454
+ [self stopRingback ];
455
+ }
456
+
428
457
[self stopSpin ];
429
458
[self toggleUIState: YES showCallControl: NO ];
430
459
[self .placeCallButton setTitle: @" Call" forState: UIControlStateNormal];
@@ -686,4 +715,46 @@ - (void)performAnswerVoiceCallWithUUID:(NSUUID *)uuid
686
715
}
687
716
}
688
717
718
+ #pragma mark - Ringtone
719
+
720
+ - (void )playRingback {
721
+ NSString *ringtonePath = [[NSBundle mainBundle ] pathForResource: @" ringtone" ofType: @" wav" ];
722
+ if ([ringtonePath length ] <= 0 ) {
723
+ NSLog (@" Can't find sound file" );
724
+ return ;
725
+ }
726
+
727
+ NSError *error;
728
+ self.ringtonePlayer = [[AVAudioPlayer alloc ] initWithContentsOfURL: [NSURL URLWithString: ringtonePath] error: &error];
729
+ if (error != nil ) {
730
+ NSLog (@" Failed to initialize audio player: %@ " , error);
731
+ } else {
732
+ self.ringtonePlayer .delegate = self;
733
+ self.ringtonePlayer .numberOfLoops = -1 ;
734
+
735
+ self.ringtonePlayer .volume = 1 .0f ;
736
+ [self .ringtonePlayer play ];
737
+ }
738
+ }
739
+
740
+ - (void )stopRingback {
741
+ if (!self.ringtonePlayer .isPlaying ) {
742
+ return ;
743
+ }
744
+
745
+ [self .ringtonePlayer stop ];
746
+ }
747
+
748
+ - (void )audioPlayerDidFinishPlaying : (AVAudioPlayer *)player successfully : (BOOL )flag {
749
+ if (flag) {
750
+ NSLog (@" Audio player finished playing successfully" );
751
+ } else {
752
+ NSLog (@" Audio player finished playing with some error" );
753
+ }
754
+ }
755
+
756
+ - (void )audioPlayerDecodeErrorDidOccur : (AVAudioPlayer *)player error : (NSError *)error {
757
+ NSLog (@" Decode error occurred: %@ " , error);
758
+ }
759
+
689
760
@end
0 commit comments