1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-02 09:27:55 +01:00
Telegram/Telegraph/TGBridgeAudioHandler.m
2016-02-25 01:03:51 +01:00

213 lines
9.4 KiB
Objective-C

#import "TGBridgeAudioHandler.h"
#import "TGBridgeAudioSubscription.h"
#import "TGBridgeAudioMediaAttachment+TGAudioMediaAttachment.h"
#import "TGBridgeDocumentMediaAttachment+TGDocumentMediaAttachment.h"
#import "TGBridgeCommon.h"
#import "TGBridgeServer.h"
#import "TGBridgeAudioEncoder.h"
#import "TGBridgeAudioDecoder.h"
#import "TGDownloadAudioSignal.h"
#import "TGSendAudioSignal.h"
#import "TGMessage.h"
#import "TGBridgeMessage+TGMessage.h"
@implementation TGBridgeAudioHandler
+ (SSignal *)handlingSignalForSubscription:(TGBridgeSubscription *)subscription server:(TGBridgeServer *)server
{
if ([subscription isKindOfClass:[TGBridgeAudioSubscription class]])
{
TGBridgeAudioSubscription *audioSubscription = (TGBridgeAudioSubscription *)subscription;
int64_t identifier = 0;
int64_t conversationId = audioSubscription.conversationId;
int32_t messageId = audioSubscription.messageId;
NSString *audioPath = nil;
TGMediaAttachment *attachment = nil;
if ([audioSubscription.attachment isKindOfClass:[TGBridgeAudioMediaAttachment class]])
{
TGBridgeAudioMediaAttachment *bridgeAudioAttachment = (TGBridgeAudioMediaAttachment *)audioSubscription.attachment;
identifier = audioSubscription.identifier;
TGAudioMediaAttachment *audioAttachment = [TGBridgeAudioMediaAttachment tgAudioMediaAttachmentWithBridgeAudioMediaAttachment:bridgeAudioAttachment];
audioPath = audioAttachment.localFilePath;
attachment = audioAttachment;
}
else if ([audioSubscription.attachment isKindOfClass:[TGBridgeDocumentMediaAttachment class]])
{
TGBridgeDocumentMediaAttachment *bridgeDocumentAttachment = (TGBridgeDocumentMediaAttachment *)audioSubscription.attachment;
identifier = bridgeDocumentAttachment.documentId;
TGDocumentMediaAttachment *documentAttachment = [TGBridgeDocumentMediaAttachment tgDocumentMediaAttachmentWithBridgeDocumentMediaAttachment:bridgeDocumentAttachment];
audioPath = [TGDownloadAudioSignal pathForDocumentMediaAttachment:documentAttachment];
attachment = documentAttachment;
}
bool audioDownloaded = [[NSFileManager defaultManager] fileExistsAtPath:audioPath];
SSignal *(^convertSignal)(NSURL *) = ^(NSURL *url)
{
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
{
TGBridgeAudioDecoder *decoder = [[TGBridgeAudioDecoder alloc] initWithURL:url];
[decoder startWithCompletion:^(NSURL *result)
{
NSURL *finalURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@.%@", result.lastPathComponent, @"m4a"] relativeToURL:server.temporaryFilesURL];
[[NSFileManager defaultManager] moveItemAtURL:result toURL:finalURL error:nil];
if (result != nil)
{
[subscriber putNext:finalURL];
[subscriber putCompletion];
}
else
{
[subscriber putError:nil];
}
}];
return [[SBlockDisposable alloc] initWithBlock:^
{
[decoder stop];
}];
}];
};
SSignal *(^sendSignal)(NSURL *, NSString *) = ^SSignal *(NSURL *url, NSString *key)
{
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
{
[server sendFileWithURL:url metadata:@{ TGBridgeIncomingFileTypeKey: TGBridgeIncomingFileTypeAudio, TGBridgeIncomingFileIdentifierKey: key }];
[subscriber putNext:@true];
[subscriber putCompletion];
return nil;
}];
};
SSignal *(^processSignal)(NSURL *) = ^(NSURL *url)
{
return [convertSignal(url) mapToSignal:^(NSURL *resultUrl)
{
return sendSignal(resultUrl, [NSString stringWithFormat:@"%lld", identifier]);
}];
};
if (audioDownloaded)
{
return processSignal([NSURL fileURLWithPath:audioPath]);
}
else
{
return [[TGDownloadAudioSignal downloadAudioWithAttachment:attachment conversationId:conversationId messageId:messageId] mapToSignal:^(NSString *audioPath)
{
return processSignal([NSURL fileURLWithPath:audioPath]);
}];
}
}
else if ([subscription isKindOfClass:[TGBridgeAudioSentSubscription class]])
{
return [server pipeForKey:@"sentAudio"];
}
return [SSignal fail:nil];
}
+ (NSArray *)handledSubscriptions
{
return @[ [TGBridgeAudioSubscription class], [TGBridgeAudioSentSubscription class] ];
}
+ (void)handleIncomingAudioWithURL:(NSURL *)url metadata:(NSDictionary *)metadata server:(TGBridgeServer *)server
{
int64_t uniqueId = [metadata[TGBridgeIncomingFileRandomIdKey] int64Value];
int64_t peerId = [metadata[TGBridgeIncomingFilePeerIdKey] int64Value];
int32_t replyToMid = [metadata[TGBridgeIncomingFileReplyToMidKey] int32Value];
NSURL *tempURL = [NSURL URLWithString:url.lastPathComponent relativeToURL:server.temporaryFilesURL];
NSError *error;
[[NSFileManager defaultManager] moveItemAtURL:url toURL:tempURL error:&error];
NSString *signalKey = [[NSString alloc] initWithFormat:@"convertAudio_%lld", uniqueId];
[server startSignalForKey:signalKey producer:^SSignal *
{
SSignal *convertSignal = [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
{
TGBridgeAudioEncoder *encoder = [[TGBridgeAudioEncoder alloc] initWithURL:tempURL];
[encoder startWithCompletion:^(TGDataItem *dataItem, int32_t duration, TGLiveUploadActorData *liveData)
{
if (dataItem != nil)
{
NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
result[@"dataItem"] = dataItem;
result[@"duration"] = @(duration);
if (liveData != nil)
result[@"liveData"] = liveData;
[subscriber putNext:result];
[subscriber putCompletion];
}
else
{
[subscriber putError:nil];
}
}];
return nil;
}];
return [convertSignal mapToSignal:^SSignal *(NSDictionary *result)
{
return [[TGSendAudioSignal sendAudioWithPeerId:peerId tempDataItem:result[@"dataItem"] liveData:result[@"liveData"] duration:[result[@"duration"] int32Value] localAudioId:uniqueId replyToMid:replyToMid] onNext:^(TGMessage *next)
{
for (TGMediaAttachment *attachment in next.mediaAttachments)
{
if ([attachment isKindOfClass:[TGAudioMediaAttachment class]])
{
TGAudioMediaAttachment *audioAttachment = (TGAudioMediaAttachment *)attachment;
if (audioAttachment.audioId != 0)
{
TGBridgeMessage *bridgeMessage = [TGBridgeMessage messageWithTGMessage:next];
for (TGBridgeMediaAttachment *bridgeAttachment in bridgeMessage.media)
{
if ([bridgeAttachment isKindOfClass:[TGBridgeAudioMediaAttachment class]])
{
TGBridgeAudioMediaAttachment *bridgeAudioAttachment = (TGBridgeAudioMediaAttachment *)bridgeAttachment;
bridgeAudioAttachment.localAudioId = uniqueId;
}
}
[server putNext:bridgeMessage forKey:@"sentAudio"];
}
}
else if ([attachment isKindOfClass:[TGDocumentMediaAttachment class]])
{
TGDocumentMediaAttachment *documentAttachment = (TGDocumentMediaAttachment *)attachment;
if (documentAttachment.documentId != 0)
{
TGBridgeMessage *bridgeMessage = [TGBridgeMessage messageWithTGMessage:next];
for (TGBridgeMediaAttachment *bridgeAttachment in bridgeMessage.media)
{
if ([bridgeAttachment isKindOfClass:[TGBridgeDocumentMediaAttachment class]])
{
TGBridgeDocumentMediaAttachment *bridgeDocumentAttachment = (TGBridgeDocumentMediaAttachment *)bridgeAttachment;
bridgeDocumentAttachment.localDocumentId = uniqueId;
}
}
[server putNext:bridgeMessage forKey:@"sentAudio"];
}
}
}
}];
}];
}];
}
@end