mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 11:08:06 +00:00
233 lines
8 KiB
Objective-C
233 lines
8 KiB
Objective-C
/*
|
|
* Copyright (c) 2010-2020 Belledonne Communications SARL.
|
|
*
|
|
* This file is part of linphone-iphone
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#import "UILinphoneAudioPlayer.h"
|
|
#import "Utils.h"
|
|
#import "PhoneMainView.h"
|
|
|
|
@implementation UILinphoneAudioPlayer {
|
|
@private
|
|
LinphonePlayer *player;
|
|
LinphonePlayerCbs *cbs;
|
|
int duration;
|
|
BOOL eofReached;
|
|
}
|
|
|
|
@synthesize file;
|
|
|
|
#pragma mark - Factory
|
|
|
|
+ (id)audioPlayerWithFilePath:(NSString *)filePath {
|
|
return [[self alloc] initWithFilePath:filePath];
|
|
}
|
|
|
|
#pragma mark - Life cycle
|
|
|
|
- (instancetype)initWithFilePath:(NSString *)filePath {
|
|
if (self = [super initWithNibName:NSStringFromClass(self.class) bundle:[NSBundle mainBundle]]) {
|
|
player = linphone_core_create_local_player(LC, NULL, "IOSDisplay", NULL);
|
|
cbs = linphone_player_get_callbacks(player);
|
|
linphone_player_set_user_data(player, (__bridge void *)self);
|
|
linphone_player_cbs_set_eof_reached(cbs, on_eof_reached);
|
|
file = filePath;
|
|
eofReached = NO;
|
|
_refreshTimer = nil;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[self close];
|
|
}
|
|
|
|
- (void)close {
|
|
if (player) {
|
|
[_refreshTimer invalidate];
|
|
_refreshTimer = nil;
|
|
linphone_player_close(player);
|
|
linphone_player_unref(player);
|
|
player = NULL;
|
|
}
|
|
[self.view removeFromSuperview];
|
|
}
|
|
|
|
- (void)viewDidAppear:(BOOL)animated {
|
|
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
|
if (player && linphone_player_get_state(player) == LinphonePlayerPlaying)
|
|
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPause:[UIColor blackColor]] forState:UIControlStateNormal];
|
|
else
|
|
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
|
[_stopButton setTitle:@"" forState:UIControlStateNormal];
|
|
[_stopButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemRefresh:[UIColor blackColor]] forState:UIControlStateNormal];
|
|
}
|
|
|
|
- (void)viewWillDisappear:(BOOL)animated {
|
|
[self close];
|
|
}
|
|
|
|
- (void)open {
|
|
linphone_player_open(player, file.UTF8String);
|
|
duration = linphone_player_get_duration(player);
|
|
[self updateTimeLabel:0];
|
|
_timeProgress.progress = 0;
|
|
|
|
eofReached = NO;
|
|
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
|
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
|
[_stopButton setTitle:@"" forState:UIControlStateNormal];
|
|
[_stopButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemRefresh:[UIColor blackColor]] forState:UIControlStateNormal];
|
|
if (linphone_player_get_is_video_available(player)) {
|
|
linphone_player_set_window_id(player, (__bridge void *)VIEW(RecordingsListView).videoView);
|
|
VIEW(RecordingsListView).videoView.hidden = NO;
|
|
} else {
|
|
VIEW(RecordingsListView).videoView.hidden = YES;
|
|
}
|
|
}
|
|
|
|
- (BOOL)isOpened {
|
|
return player && linphone_player_get_state(player) != LinphonePlayerClosed;
|
|
}
|
|
|
|
- (BOOL)isCreated {
|
|
return player!=nil;
|
|
}
|
|
|
|
- (void)setFile:(NSString *)fileName {
|
|
if (player) linphone_player_close(player);
|
|
file = fileName;
|
|
}
|
|
|
|
#pragma mark - Callbacks
|
|
|
|
void on_eof_reached(LinphonePlayer *pl) {
|
|
NSLog(@"EOF reached");
|
|
UILinphoneAudioPlayer *player = (__bridge UILinphoneAudioPlayer *)linphone_player_get_user_data(pl);
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[player.playButton setTitle:@"" forState:UIControlStateNormal];
|
|
[player.playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
|
});
|
|
player->eofReached = YES;
|
|
VIEW(RecordingsListView).videoView.hidden = YES;
|
|
}
|
|
|
|
#pragma mark - ViewController methods
|
|
|
|
- (void)viewDidLoad {
|
|
[super viewDidLoad];
|
|
}
|
|
|
|
- (void)didReceiveMemoryWarning {
|
|
[super didReceiveMemoryWarning];
|
|
}
|
|
|
|
#pragma mark - Utils
|
|
|
|
+ (NSString *)timeToString:(int)time {
|
|
time /= 1000;
|
|
int hours = time / 3600;
|
|
time %= 3600;
|
|
int minutes = time / 60;
|
|
int seconds = time % 60;
|
|
NSNumberFormatter *formatter = [NSNumberFormatter new];
|
|
formatter.maximumIntegerDigits = 2;
|
|
formatter.minimumIntegerDigits = 2;
|
|
NSString *ret = [NSString stringWithFormat:@"%@:%@",
|
|
[formatter stringFromNumber:[NSNumber numberWithInt:minutes]],
|
|
[formatter stringFromNumber:[NSNumber numberWithInt:seconds]]];
|
|
ret = (hours == 0)?ret:[[NSString stringWithFormat:@"%d:", hours] stringByAppendingString:ret];
|
|
return ret;
|
|
}
|
|
|
|
#pragma mark - Updating
|
|
|
|
- (void)updateTimeLabel:(int)currentTime {
|
|
_timeLabel.text = [NSString stringWithFormat:@"%@ / %@", [self.class timeToString:currentTime], [self.class timeToString:duration]];
|
|
}
|
|
|
|
- (void)displayProgress{
|
|
int pos = linphone_player_get_current_position(player);
|
|
_timeProgress.progress = (float)pos / (float)duration;
|
|
[self updateTimeLabel:pos];
|
|
}
|
|
|
|
- (void)update {
|
|
if (!_refreshTimer)
|
|
_refreshTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(displayProgress) userInfo:nil repeats:YES];
|
|
}
|
|
|
|
- (void)pause {
|
|
if ([self isOpened]) {
|
|
linphone_player_pause(player);
|
|
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
|
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Event handlers
|
|
|
|
- (IBAction)onPlay:(id)sender {
|
|
if (eofReached) {
|
|
linphone_player_seek(player, 0);
|
|
eofReached = NO;
|
|
}
|
|
LinphonePlayerState state = linphone_player_get_state(player);
|
|
switch (state) {
|
|
case LinphonePlayerClosed:
|
|
break;
|
|
case LinphonePlayerPaused:
|
|
NSLog(@"Play");
|
|
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
|
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPause:[UIColor blackColor]] forState:UIControlStateNormal];
|
|
linphone_player_start(player);
|
|
break;
|
|
case LinphonePlayerPlaying:
|
|
NSLog(@"Pause");
|
|
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
|
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
|
linphone_player_pause(player);
|
|
break;
|
|
}
|
|
[self update];
|
|
}
|
|
|
|
- (IBAction)onStop:(id)sender {
|
|
NSLog(@"Stop");
|
|
linphone_player_pause(player);
|
|
linphone_player_seek(player, 0);
|
|
eofReached = NO;
|
|
[_playButton setTitle:@"" forState:UIControlStateNormal];
|
|
[_playButton setImage:[UIImage imageFromSystemBarButton:UIBarButtonSystemItemPlay:[UIColor blackColor]] forState:UIControlStateNormal];
|
|
_timeProgress.progress = 0;
|
|
[self updateTimeLabel:0];
|
|
}
|
|
|
|
- (IBAction)onTapTimeBar:(UITapGestureRecognizer *)sender {
|
|
if (sender.state != UIGestureRecognizerStateEnded)
|
|
return;
|
|
CGPoint loc = [sender locationInView:self.view];
|
|
CGPoint timeLoc = _timeProgress.frame.origin;
|
|
CGSize timeSize = _timeProgress.frame.size;
|
|
if (loc.x >= timeLoc.x && loc.x <= timeLoc.x + timeSize.width && loc.y >= timeLoc.y - 10 && loc.y <= timeLoc.y + timeSize.height + 10) {
|
|
float progress = (loc.x - timeLoc.x) / timeSize.width;
|
|
_timeProgress.progress = progress;
|
|
[self updateTimeLabel:(int)(progress * duration)];
|
|
linphone_player_seek(player, (int)(progress * duration));
|
|
}
|
|
}
|
|
@end
|