张育玮 发表于 2021-9-4 17:45:01

Mac系统C++如何播放MP3?

Mac系统下C++无法使用Windows.h头文件的Beep,该如何播放MP3呢?
最好是C++自带的头文件,如果不是,请写下头文件的下载地址哦

mei-mo 发表于 2021-9-4 21:46:40

Windows的程序我也在Mac上运行不了{:5_94:}

张育玮 发表于 2021-9-5 11:22:53

mei-mo 发表于 2021-9-4 21:46
Windows的程序我也在Mac上运行不了

我也是

lin53 发表于 2021-9-5 13:04:55

mei-mo 发表于 2021-9-4 21:46
Windows的程序我也在Mac上运行不了

可能系统不一样吧

Mike_python小 发表于 2021-9-5 21:34:22

mei-mo 发表于 2021-9-4 21:46
Windows的程序我也在Mac上运行不了

你指的是exe吗……

人造人 发表于 2021-9-6 15:48:12

下面这个代码花了我大概三天的时间,因为学到了很多东西,所以值得,^_^

音频视频处理领域,ffmpeg 大概是最权威的了
ffmpeg 跨平台,mac 肯定能用
我的程序中还使用了 /dev/dsp 设备,不知道 mac 能不能用
这个程序把解码出来的音频数据发往 dsp 设备,如果 dsp 设备不能用,那就使用 sdl,把发往 dsp 的数据发送到 sdl 进行播放
还有,因为使用了 ffmpeg,这个程序可不仅仅支持 mp3,ffmpeg 支持绝大多数的音频视频格式
还有,我刚刚才看到是要求 C++ 写,C语言代码在下面,如果你真的必须是要 C++ 的话,自己改代码吧,^_^
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>
#include <libavformat/avformat.h>
#include <libavcodec/codec.h>
#include <libswresample/swresample.h>

int main(int argc, char *argv[]) {
    if(argc != 2) return -1;
    const char *filename = argv;
    AVFormatContext *format_ctx = avformat_alloc_context();
    avformat_open_input(&format_ctx, filename, NULL, NULL);
    avformat_find_stream_info(format_ctx, NULL);
    int stream_idx = av_find_best_stream(format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
    AVCodecParameters *codecpar = format_ctx->streams->codecpar;
    AVCodec *codec = avcodec_find_decoder(codecpar->codec_id);
    AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
    avcodec_parameters_to_context(codec_ctx, codecpar);
    avcodec_open2(codec_ctx, codec, NULL);

    int dsp = open("/dev/dsp", O_WRONLY);
    int channels = codecpar->channels;
    int sample_rate = codecpar->sample_rate;
    int sample_fmt = AFMT_S16_LE;   // dsp 有好多格式都不支持,这里使用固定格式,下面把数据转换到这个格式
    ioctl(dsp, SNDCTL_DSP_CHANNELS, &channels);
    ioctl(dsp, SNDCTL_DSP_SPEED, &sample_rate);
    ioctl(dsp, SNDCTL_DSP_SETFMT, &sample_fmt);
    printf("channels: %d, sample_rate: %d, sample_fmt: %d\n", channels, sample_rate,
            av_get_bytes_per_sample(codecpar->format) * 8);
    SwrContext *swr_ctx = swr_alloc();
    int channel_layout = av_get_default_channel_layout(codecpar->channels);   // codecpar->channel_layout 有可能为 0
    swr_alloc_set_opts(swr_ctx, channel_layout, AV_SAMPLE_FMT_S16, codecpar->sample_rate,
            channel_layout, codecpar->format, codecpar->sample_rate, 0, NULL);
    swr_init(swr_ctx);
    AVPacket *pkt = av_packet_alloc();
    AVFrame *frame = av_frame_alloc();
    size_t buffer_size = 48000 * 4;
    uint8_t *buffer = av_malloc(buffer_size);
    while(av_read_frame(format_ctx, pkt) == 0) {
      if(pkt->stream_index == stream_idx) {
            avcodec_send_packet(codec_ctx, pkt);
            avcodec_receive_frame(codec_ctx, frame);
            swr_convert(swr_ctx, &buffer, buffer_size, (const uint8_t **)&frame->data, frame->nb_samples);
            ssize_t nbytes = av_samples_get_buffer_size(NULL, codecpar->channels, frame->nb_samples, AV_SAMPLE_FMT_S16, 1);
            write(dsp, buffer, nbytes);
      }
      av_packet_unref(pkt);
    }
    av_free(buffer);
    av_frame_free(&frame);
    av_packet_free(&pkt);
    swr_free(&swr_ctx);
    close(dsp);

    avcodec_close(codec_ctx);
    avcodec_free_context(&codec_ctx);
    avformat_close_input(&format_ctx);
    avformat_free_context(format_ctx);
    return 0;
}


编译命令
gcc -g -Wall -o main main.c -lavformat -lavcodec -lavutil -lswresample

运行
./main test.mp3
./main test.mp4
./main test.aac
./main test.flv
...


写这个代码参考了下面这些内容,当然肯定不止这些,我没办法全部列出了
https://www.baidu.com/
https://blog.csdn.net/dux003/article/details/5459423
https://www.jianshu.com/p/8ff162ac55bd
https://www.jianshu.com/p/2f2b8e0fe540
https://stackoverflow.com/questions/59618487/swr-convert-float-planar-to-s16
https://cloud.tencent.com/developer/article/1666126
https://blog.csdn.net/woai110120130/article/details/82080648
https://blog.csdn.net/huohongpeng/article/details/119670171
https://www.jb51.net/article/201684.htm

张育玮 发表于 2021-10-2 11:29:38

人造人 发表于 2021-9-6 15:48
下面这个代码花了我大概三天的时间,因为学到了很多东西,所以值得,^_^

音频视频处理领域,ffmpeg 大概 ...

谢谢
页: [1]
查看完整版本: Mac系统C++如何播放MP3?