You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xcode 9中FFMpeg报错:‘AVMediaType’类型定义冲突及RTSP直播推流问题求解

Fixing AVMediaType Conflict & Implementing RTSP Streaming with FFmpeg in Xcode 9

Hey there! Let's break down your two FFmpeg issues and get you sorted out.


1. Resolving 'AVMediaType' Definition Conflict

This error pops up because FFmpeg's AVMediaType typedef clashes with the one from Apple's AVFoundation framework (they share the exact same name). Here are three practical fixes, ordered by ease of implementation:

Option 1: Use Macro Wrappers to Isolate FFmpeg Headers

This is the quickest fix without modifying the FFmpeg library itself. Wrap your FFmpeg header includes with macros to temporarily disable the system's AVMediaType definition:

// Save the system's AVMediaType definition
#pragma push_macro("AVMediaType")
#undef AVMediaType

// Include your FFmpeg headers here
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>

// Restore the system's AVMediaType definition
#pragma pop_macro("AVMediaType")

This way, when compiling FFmpeg code, the system's AVMediaType is hidden, and vice versa for AVFoundation code.

Option 2: Compile FFmpeg with Namespace Support

If you're building FFmpeg from source, enable the --enable-namespace flag during configuration. This wraps all FFmpeg types in a FFmpeg:: namespace, so you'd reference it as FFmpeg::AVMediaType instead of just AVMediaType.

Option 3: Rename FFmpeg's AVMediaType (Last Resort)

If you're using a precompiled FFmpeg library, you can manually edit the avutil.h header:

  • Find the line typedef enum AVMediaType AVMediaType;
  • Rename it to something like typedef enum AVMediaType FFAVMediaType;
  • Replace all references to AVMediaType in your FFmpeg-related code with FFAVMediaType.
    Note: This is tedious and requires updating every instance, so only use it if the above options don't work.

Keep in mind: RTSP streaming requires more than just avutil.h—you'll need avformat, avcodec, and swscale libraries too. Here's a step-by-step guide with code snippets:

Step 1: Initialize FFmpeg & Network

First, set up FFmpeg's core components and network support:

// Register all formats and codecs
av_register_all();
// Initialize network components (critical for RTSP)
avformat_network_init();

Step 2: Configure Output Context & RTSP URL

Create an output format context for RTSP and set your stream URL:

AVFormatContext *outputCtx = NULL;
const char *rtspUrl = "rtsp://your-stream-server-url:port/stream-name";

// Auto-detect output format from URL (should pick RTSP)
int ret = avformat_alloc_output_context2(&outputCtx, NULL, "rtsp", rtspUrl);
if (ret < 0) {
    // Handle error (use av_strerror to get readable message)
    char errBuf[1024];
    av_strerror(ret, errBuf, sizeof(errBuf));
    NSLog(@"Failed to create output context: %s", errBuf);
    return;
}

// Set RTSP transport options (TCP is more reliable for live streaming)
AVDictionary *opts = NULL;
av_dict_set(&opts, "rtsp_transport", "tcp", 0);
av_dict_set(&opts, "stimeout", "5000000", 0); // 5-second timeout

Step 3: Add Output Stream & Configure Encoder

Assuming you're streaming H.264 video (common for RTSP), create a video stream and set up the encoder:

// Create a new stream in the output context
AVStream *outStream = avformat_new_stream(outputCtx, NULL);
if (!outStream) {
    NSLog(@"Failed to create output stream");
    goto cleanup;
}

// Set stream parameters (match your input video's specs)
AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_H264);
AVCodecContext *codecCtx = avcodec_alloc_context3(codec);

codecCtx->codec_id = AV_CODEC_ID_H264;
codecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
codecCtx->pix_fmt = AV_PIX_FMT_YUV420P; // Required for H.264
codecCtx->width = 1280; // Your video width
codecCtx->height = 720; // Your video height
codecCtx->bit_rate = 2000000; // 2Mbps bitrate
codecCtx->time_base = (AVRational){1, 30}; // 30fps
codecCtx->framerate = (AVRational){30, 1};

// Copy codec params to output stream
avcodec_parameters_from_context(outStream->codecpar, codecCtx);

// Open the encoder
ret = avcodec_open2(codecCtx, codec, &opts);
if (ret < 0) {
    char errBuf[1024];
    av_strerror(ret, errBuf, sizeof(errBuf));
    NSLog(@"Failed to open encoder: %s", errBuf);
    goto cleanup;
}

Step 4: Open Output IO & Write Header

Connect to the RTSP server and send the stream header:

// Open the RTSP output
ret = avio_open2(&outputCtx->pb, rtspUrl, AVIO_FLAG_WRITE, NULL, &opts);
if (ret < 0) {
    char errBuf[1024];
    av_strerror(ret, errBuf, sizeof(errBuf));
    NSLog(@"Failed to open RTSP output: %s", errBuf);
    goto cleanup;
}

// Write the stream header to the server
ret = avformat_write_header(outputCtx, &opts);
if (ret < 0) {
    char errBuf[1024];
    av_strerror(ret, errBuf, sizeof(errBuf));
    NSLog(@"Failed to write header: %s", errBuf);
    goto cleanup;
}

Step 5: Encode & Send Frames

For each video frame you capture (e.g., from iOS camera), convert it to the encoder's pixel format, encode it, and send it to the server:

// Example: Convert a captured CMSampleBuffer to AVFrame (you'll need to implement this)
AVFrame *frame = convertCMSampleBufferToAVFrame(sampleBuffer);

// Send frame to encoder
ret = avcodec_send_frame(codecCtx, frame);
if (ret < 0) {
    // Handle send error
    continue;
}

// Receive encoded packets
AVPacket pkt = {0};
av_init_packet(&pkt);
while (ret >= 0) {
    ret = avcodec_receive_packet(codecCtx, &pkt);
    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
        break;
    } else if (ret < 0) {
        // Handle receive error
        break;
    }

    // Set packet stream index and time base
    pkt.stream_index = outStream->index;
    av_packet_rescale_ts(&pkt, codecCtx->time_base, outStream->time_base);

    // Write packet to RTSP stream
    ret = av_interleaved_write_frame(outputCtx, &pkt);
    av_packet_unref(&pkt);
}

Step 6: Cleanup Resources

When you're done streaming, make sure to release all FFmpeg resources properly:

cleanup:
// Write trailer
av_write_trailer(outputCtx);
// Close encoder
avcodec_close(codecCtx);
// Close output IO
avio_close(outputCtx->pb);
// Free context
avformat_free_context(outputCtx);
// Clean up network
avformat_network_deinit();

内容的提问来源于stack exchange,提问作者Vineesh TP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:29:19