im client iOS端将android端录制的格式为amr的语音转码为wav格式

用到一个开源的库:opencore-amr for ios

 

https://github.com/feuvan/opencore-amr-iOS

1.下载后运行xcode脚本,

2.脚本运行完成后,看到目录下test里面有例子,即解压和压缩的例子

  我试了下,用amrn-dec.c

+(DDMessageEntity *)makeMessageFromStream:(DDDataInputStream *)bodyData
{
    int32_t seqNo = [bodyData readInt];
    NSString *fromUserId = [bodyData readUTF];
    NSString *toUserId = [bodyData readUTF];
    int32_t msgTime = [bodyData readInt];
    int8_t msgType = [bodyData readChar];
    //int8_t msgRenderType = [bodyData readChar];
    DDMessageEntity *msg = [[DDMessageEntity alloc ] init];
    msg.msgType = msgType;
    msg.msgContentType = msgType;
    NSString* messageContent = nil;
    NSMutableDictionary* info = [[NSMutableDictionary alloc] init];
    if (msgType == DDMessageTypeVoice || msgType == DDGroup_MessageTypeVoice) {
        if (msgType ==DDMessageTypeVoice) {
            msg.msgType = MESSAGE_TYPE_SINGLE;
            msg.msgContentType =DDMessageTypeVoice;
        }else{
            msg.msgType = MESSAGE_TYPE_TEMP_GROUP;
            msg.msgContentType =DDGroup_MessageTypeVoice;
        }
        int32_t dataLength = [bodyData readInt];
        NSData* data = [bodyData readDataWithLength:dataLength];
        NSData* voiceData = [data subdataWithRange:NSMakeRange(4, [data length] - 4)];
        NSString* filename = [NSString stringWithString:[Encapsulator defaultFileName]];
        //....---------------------*********
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *voiceDirectory = [documentsDirectory stringByAppendingPathComponent:@"voice"];
        if ( ! [[NSFileManager defaultManager] fileExistsAtPath:voiceDirectory]) {
            [[NSFileManager defaultManager] createDirectoryAtPath:voiceDirectory withIntermediateDirectories:YES attributes:nil error:NULL];
        }
        NSString* fileAmrName = [voiceDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%.0f.amr", [[NSDate date] timeIntervalSince1970]]];
        
        NSString* fileWavName = [voiceDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%.0f.wav", [[NSDate date] timeIntervalSince1970]]];
        
        if ([voiceData writeToFile:fileAmrName atomically:YES])
        {
            int decode = [MKServerHelper amrwbDec:2 sourcefile:fileAmrName AndTargetFile:fileWavName];
            
            if (decode == 0) {
                NSLog(@"格式转换成功");

            }
        }
        else
        {
            NSLog(@"语音存储出错");
        }
        
        
        //....---------------------*********
        if ([voiceData writeToFile:filename atomically:YES])
        {
            messageContent = filename;
        }
        else
        {
            messageContent = @"语音存储出错";
        }
        NSData* voiceLengthData = [data subdataWithRange:NSMakeRange(0, 4)];
        
        int8_t ch1;
        [voiceLengthData getBytes:&ch1 range:NSMakeRange(0,1)];
        ch1 = ch1 & 0x0ff;
        
        int8_t ch2;
        [voiceLengthData getBytes:&ch2 range:NSMakeRange(1,1)];
        ch2 = ch2 & 0x0ff;
        
        int32_t ch3;
        [voiceLengthData getBytes:&ch3 range:NSMakeRange(2,1)];
        ch3 = ch3 & 0x0ff;
        
        int32_t ch4;
        [voiceLengthData getBytes:&ch4 range:NSMakeRange(3,1)];
        ch4 = ch4 & 0x0ff;
        
        if ((ch1 | ch2 | ch3 | ch4) < 0){
            @throw [NSException exceptionWithName:@"Exception" reason:@"EOFException" userInfo:nil];
        }
        int voiceLength = ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
        [info setObject:@(voiceLength) forKey:VOICE_LENGTH];
        [info setObject:@(0) forKey:DDVOICE_PLAYED];
    }else
    {
        messageContent = (NSString *)[bodyData readUTF];
        if ([messageContent hasPrefix:DD_MESSAGE_IMAGE_PREFIX])
        {
            msg.msgContentType = DDMessageTypeImage;
        }
    }
    NSString *attach = [bodyData readUTF];
    msg.msgID = [DDMessageModule getMessageID];
    msg.seqNo = seqNo;
    msg.msgTime = msgTime;
    msg.toUserID=toUserId;
    msg.msgContent = [msg getNewMessageContentFromContent:messageContent];
    msg.attach = attach;
    if([msg isGroupMessage])
    {
        msg.sessionId = toUserId;       //群聊时,toUserId表示会话ID
        msg.senderId = fromUserId;      //群聊时,fromUserId表示发送者I
    }
    else
    {
        msg.sessionId = fromUserId; //单人时,fromUserId表示发送者ID,作为会话id
        msg.senderId = fromUserId;  //单人时,fromUserId表示发送者ID
        
    }
    if ([msg.sessionId isEqualToString:TheRuntime.userID]) {
        msg.sessionId = toUserId;
    }
      msg.info=info;
    return msg;
}

 

Helper:

+(int )amrwbDec :(int ) argc sourcefile:(NSString*)sourceFile AndTargetFile:(NSString*) targetFile
{
//    char *argv[10];
    
    const int sizes[] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 6, 5, 5, 0, 0, 0, 0 };
    
    FILE* in;
    char header[6];
    int n;
    void *wav, *amr;
    
    in = fopen([sourceFile UTF8String] , "rb");
    if (!in) {
        perror([sourceFile UTF8String]);
        return 1;
    }
    n = fread(header, 1, 6, in);
    if (n != 6 || memcmp(header, "#!AMR\n", 6)) {
        fprintf(stderr, "Bad header\n");
        return 1;
    }
    
    wav = wav_write_open([targetFile UTF8String], 8000, 16, 1);
    if (!wav) {
        fprintf(stderr, "Unable to open %s\n", [targetFile UTF8String]);
        return 1;
    }
    
    amr = Decoder_Interface_init();
    while (1) {
        uint8_t buffer[500], littleendian[320], *ptr;
        int size, i;
        int16_t outbuffer[160];
        /* Read the mode byte */
        n = fread(buffer, 1, 1, in);
        if (n <= 0)
            break;
        /* Find the packet size */
        size = sizes[(buffer[0] >> 3) & 0x0f];
        n = fread(buffer + 1, 1, size, in);
        if (n != size)
            break;
        
        /* Decode the packet */
        Decoder_Interface_Decode(amr, buffer, outbuffer, 0);
        
        /* Convert to little endian and write to wav */
        ptr = littleendian;
        for (i = 0; i < 160; i++) {
            *ptr++ = (outbuffer[i] >> 0) & 0xff;
            *ptr++ = (outbuffer[i] >> 8) & 0xff;
        }
        wav_write_data(wav, littleendian, 320);
    }
    fclose(in);
    Decoder_Interface_exit(amr);
    wav_write_close(wav);
    return 0;
}

生成的.wav文件用itools打开该应用,到voice目录下就可以找到,

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。