gpt4 book ai didi

ios - 如何在 iOS 上将 flac 转换为 wav?

转载 作者:行者123 更新时间:2023-12-04 23:26:39 26 4
gpt4 key购买 nike

我有一个用 FLAC 编码的文件,我想将其转换为 WAV。

我已添加 this FFMpeg lib到我的项目并导入它。

我看到一些来自 this answer 的代码,但我不清楚如何使用它:

#import "avformat.h"

// Some code goes here

/*
* avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
*/
int openInputValue = avformat_open_input(&pFormatCtx, utf8FilePath, inputFormat, nil);
NSLog(@"%s - %d # openInputValue = %d", __PRETTY_FUNCTION__, __LINE__, openInputValue);

我目前在一个函数中有这个代码,它需要 NSData持有 FLAC 文件。 如果 avformat_open_input是正确的调用,我该如何设置变量?如果它不是正确的调用,那是什么?

This question似乎是重复的,但实际上并没有很好的答案。

另请注意,我不想要球员。该文件包含 MQA,因此我需要通过我自己的自定义解码器运行它。

最佳答案

我能够使用 this code 来实现它用于解码和this code实际编写 WAV header /正文。

作为额外的奖励,this在解码 NSData 而不是文件时非常有帮助。

这是我完成的解码器,尽管我不希望它在任何情况下都能正常工作,除了我的。

//
// FlacToWavConverter.m
// SuperpoweredMQAExample
//
// Created by Tony Lawrence on 5/18/17.
// Copyright © 2017 imect. All rights reserved.
//

#import "FlacToWavConverter.h"
#import "avformat.h"
#import "avcodec.h"
#import "avutil.h"
#import "swresample.h"
#import "file.h"

@implementation FlacToWavConverter

+(NSURL*)convertFlacToWav:(NSData*)data {

//const char* input_filename = [filePath UTF8String];
int buffer_size = 16384;

// This call is necessarily done once in your app to initialize
// libavformat to register all the muxers, demuxers and protocols.
av_register_all();

// A media container
AVFormatContext* container = avformat_alloc_context();

//Make a custom IO context so that we can read from memory instead of a file...
unsigned char* iobuffer = av_malloc(buffer_size);
struct buffer_data bd = { 0 };
bd.ptr = (uint8_t*)data.bytes;
bd.size = data.length;
AVIOContext* ioContext = avio_alloc_context(iobuffer, buffer_size, 0, &bd, &read_packet, NULL, NULL);

container->pb = ioContext;

if (avformat_open_input(&container, "arbitrary", NULL, NULL) < 0) {
NSLog(@"Could not open file");
}

if (avformat_find_stream_info(container, NULL) < 0) {
NSLog(@"Could not find file info");
}

int stream_id = -1;

// To find the first audio stream. This process may not be necessary
// if you can gurarantee that the container contains only the desired
// audio stream
int i;
for (i = 0; i < container->nb_streams; i++) {
if (container->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
stream_id = i;
break;
}
}

if (stream_id == -1) {
NSLog(@"Could not find an audio stream");
}

// Extract some metadata
AVDictionary* metadata = container->metadata;

// Find the apropriate codec and open it
AVCodecContext* codec_context = container->streams[stream_id]->codec;

AVCodec* codec = avcodec_find_decoder(codec_context->codec_id);

if (avcodec_open2(codec_context, codec, NULL) < 0) {
NSLog(@"Could not find open the needed codec");
}

NSMutableData *pcmFile = [NSMutableData new];

AVPacket packet;
int8_t buffer[buffer_size];

while (1) {

//buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;

// Read one packet into `packet`
if (av_read_frame(container, &packet) < 0) {
break; // End of stream. Done decoding.
}

// Decodes from `packet` into the buffer
if (avcodec_decode_audio3(codec_context, (int16_t*)buffer, &buffer_size, &packet) < 1) {
break; // Error in decoding
}

// Send the buffer contents to the audio device
[pcmFile appendBytes:buffer length:buffer_size];

}

avformat_close_input(&container);

//fprintf(stdout, "Done playing. Exiting...");

NSURL *file = [FlacToWavConverter getAndCreatePlayableFileFromPcmData:pcmFile];

NSLog(@"Got a playable file maybe? %@", [file absoluteString]);

return file;
}

+(NSURL *) getAndCreatePlayableFileFromPcmData:(NSData *)data
{
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
NSString *wavFilePath = [docsDir stringByAppendingPathComponent:@"output.wav"];

//NSLog(@"PCM data : %@",data);

FILE *fout;

short NumChannels = 2;
short BitsPerSample = 16;
int SamplingRate = 44100;
int numOfSamples = [data length];

int ByteRate = NumChannels*BitsPerSample*SamplingRate/8;
short BlockAlign = NumChannels*BitsPerSample/8;
int DataSize = NumChannels*numOfSamples*BitsPerSample/8;
int chunkSize = 16;
int totalSize = 46 + DataSize;
short audioFormat = 1;

if((fout = fopen([wavFilePath cStringUsingEncoding:1], "w")) == NULL)
{
printf("Error opening out file ");
}

fwrite("RIFF", sizeof(char), 4,fout);
fwrite(&totalSize, sizeof(int), 1, fout);
fwrite("WAVE", sizeof(char), 4, fout);
fwrite("fmt ", sizeof(char), 4, fout);
fwrite(&chunkSize, sizeof(int),1,fout);
fwrite(&audioFormat, sizeof(short), 1, fout);
fwrite(&NumChannels, sizeof(short),1,fout);
fwrite(&SamplingRate, sizeof(int), 1, fout);
fwrite(&ByteRate, sizeof(int), 1, fout);
fwrite(&BlockAlign, sizeof(short), 1, fout);
fwrite(&BitsPerSample, sizeof(short), 1, fout);
fwrite("data", sizeof(char), 4, fout);
fwrite(&DataSize, sizeof(int), 1, fout);

fclose(fout);

NSMutableData *pamdata = [NSMutableData dataWithData:data];
NSFileHandle *handle;
handle = [NSFileHandle fileHandleForUpdatingAtPath:wavFilePath];
[handle seekToEndOfFile];
[handle writeData:pamdata];
[handle closeFile];

NSLog(@"Saved wav: %@", wavFilePath);

return [NSURL URLWithString:wavFilePath];
}

struct buffer_data {
uint8_t *ptr;
size_t size; ///< size left in the buffer
};


static int read_packet(void *opaque, uint8_t *buf, int buf_size)
{
struct buffer_data *bd = (struct buffer_data *)opaque;
buf_size = FFMIN(buf_size, bd->size);
//printf("ptr:%p size:%zu\n", bd->ptr, bd->size);
/* copy internal buffer data to buf */
memcpy(buf, bd->ptr, buf_size);
bd->ptr += buf_size;
bd->size -= buf_size;
return buf_size;
}

@end

关于ios - 如何在 iOS 上将 flac 转换为 wav?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43940057/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com