Recherche avancée

Médias (1)

Mot : - Tags -/artwork

Autres articles (57)

  • Mise à jour de la version 0.1 vers 0.2

    24 juin 2013, par

    Explications des différents changements notables lors du passage de la version 0.1 de MediaSPIP à la version 0.3. Quelles sont les nouveautés
    Au niveau des dépendances logicielles Utilisation des dernières versions de FFMpeg (>= v1.2.1) ; Installation des dépendances pour Smush ; Installation de MediaInfo et FFprobe pour la récupération des métadonnées ; On n’utilise plus ffmpeg2theora ; On n’installe plus flvtool2 au profit de flvtool++ ; On n’installe plus ffmpeg-php qui n’est plus maintenu au (...)

  • Personnaliser en ajoutant son logo, sa bannière ou son image de fond

    5 septembre 2013, par

    Certains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;

  • Ecrire une actualité

    21 juin 2013, par

    Présentez les changements dans votre MédiaSPIP ou les actualités de vos projets sur votre MédiaSPIP grâce à la rubrique actualités.
    Dans le thème par défaut spipeo de MédiaSPIP, les actualités sont affichées en bas de la page principale sous les éditoriaux.
    Vous pouvez personnaliser le formulaire de création d’une actualité.
    Formulaire de création d’une actualité Dans le cas d’un document de type actualité, les champs proposés par défaut sont : Date de publication ( personnaliser la date de publication ) (...)

Sur d’autres sites (8233)

  • Segmentation Analytics : How to Leverage It on Your Site

    27 octobre 2023, par Erin — Analytics Tips

    The deeper you go with your customer analytics, the better your insights will be.

    The result ? Your marketing performance soars to new heights.

    Customer segmentation is one of the best ways businesses can align their marketing strategies with an effective output to generate better results. Marketers know that targeting the right people is one of the most important aspects of connecting with and converting web visitors into customers.

    By diving into customer segmentation analytics, you’ll be able to transform your loosely defined and abstract audience into tangible, understandable segments, so you can serve them better.

    In this guide, we’ll break down customer segmentation analytics, the different types, and how you can delve into these analytics on your website to grow your business.

    What is customer segmentation ?

    Before we dive into customer segmentation analytics, let’s take a step back and look at customer segmentation in general. 

    Customer segmentation is the process of dividing your customers up into different groups based on specific characteristics.

    These groups could be based on demographics like age or location or behaviours like recent purchases or website visits. 

    By splitting your audience into different segments, your marketing team will be able to craft highly targeted and relevant marketing campaigns that are more likely to convert.

    Additionally, customer segmentation allows businesses to gain new insights into their audience. For example, by diving deep into different segments, marketers can uncover pain points and desires, leading to increased conversion rates and return on investment.

    But, to grasp the different customer segments, organisations need to know how to collect, digest and interpret the data for usable insights to improve their business. That’s where segmentation analytics comes in.

    What is customer segmentation analytics ?

    Customer segmentation analytics splits customers into different groups within your analytics software to create more detailed customer data and improve targeting.

    What is segmentation analytics?

    With customer segmentation, you’re splitting your customers into different groups. With customer segmentation analytics, you’re doing this all within your analytics platform so you can understand them better.

    One example of splitting your customers up is by country. For example, let’s say you have a global customer base. So, you go into your analytics software and find that 90% of your website visitors come from five countries : the UK, the US, Australia, Germany and Japan.

    In this area, you could then create customer segmentation subsets based on these five countries. Moving forward, you could then hop into your analytics tool at any point in time and analyse the segments by country. 

    For example, if you wanted to see how well your recent marketing campaign impacted your Japanese customers, you could look at your Japanese subset within your analytics and dive into the data.

    The primary goal of customer segmentation analytics is to gather actionable data points to give you an in-depth understanding of your customers. By gathering data on your different audience segments, you’ll discover insights on your customers that you can use to optimise your website, marketing campaigns, mobile apps, product offerings and overall customer experience.

    Rather than lumping your entire customer base into a single mass, customer segmentation analytics allows you to meet even more specific and relevant needs and pain points of your customers to serve them better.

    By allowing you to “zoom in” on your audience, segmentation analytics helps you offer more value to your customers, giving you a competitive advantage in the marketplace.

    5 types of segmentation

    There are dozens of different ways to split up your customers into segments. The one you choose depends on your goals and marketing efforts. Each type of segmentation offers a different view of your customers so you can better understand their specific needs to reach them more effectively.

    While you can segment your customers in almost endless ways, five common types the majority fall under are :

    5 Types of Segmentation

    Geographic

    Another way to segment is by geography.

    This is important because you could have drastically different interests, pain points and desires based on where you live.

    If you’re running a global e-commerce website that sells a variety of clothing products, geographic segmentation can play a crucial role in optimising your website.

    For instance, you may observe that a significant portion of your website visitors are from countries in the Southern Hemisphere, where it’s currently summer. On the other hand, visitors from the Northern Hemisphere are experiencing winter. Utilising this information, you can tailor your marketing strategy and website accordingly to increase sells.

    Where someone comes from can significantly impact how they will respond to your messaging, brand and offer.

    Geographic segmentation typically includes the following subtypes :

    • Cities (i.e., Austin, Paris, Berlin, etc.)
    • State (i.e., Massachusetts)
    • Country (i.e., Thailand)

    Psychographic

    Another key segmentation type of psychographic. This is where you split your customers into different groups based on their lifestyles.

    Psychographic segmentation is a method of dividing your customers based on their habits, attitudes, values and opinions. You can unlock key emotional elements that impact your customers’ purchasing behaviours through this segmentation type.

    Psychographic segmentation typically includes the following subtypes :

    • Values
    • Habits
    • Opinions

    Behavioural

    While psychographic segmentation looks at your customers’ overall lifestyle and habits, behavioural segmentation aims to dive into the specific individual actions they take daily, especially when interacting with your brand or your website.

    Your customers won’t all interact with your brand the same way. They’ll act differently when interacting with your products and services for several reasons. 

    Behavioural segmentation can help reveal certain use cases, like why customers buy a certain product, how often they buy it, where they buy it and how they use it.

    By unpacking these key details about your audience’s behaviour, you can optimise your campaigns and messaging to get the most out of your marketing efforts to reach new and existing customers.

    Behavioural segmentation typically includes the following subtypes :

    • Interactions
    • Interests
    • Desires

    Technographic

    Another common segmentation type is technographic segmentation. As the name suggests, this technologically driven segment seeks to understand how your customers use technology.

    While this is one of the newest segmentation types marketers use, it’s a powerful method to help you understand the types of tech your customers use, how often they use it and the specific ways they use it.

    Technographic segmentation typically includes the following subtypes :

    • Smartphone type
    • Device type : smartphone, desktop, tablet
    • Apps
    • Video games

    Demographic

    The most common approach to segmentation is to split your customers up by demographics. 

    Demographic segmentation typically includes subtypes like language, job title, age or education.

    This can be helpful for tailoring your content, products, and marketing efforts to specific audience segments. One way to capture this information is by using web analytics tools, where language is often available as a data point.

    However, for accurate insights into other demographic segments like job titles, which may not be available (or accurate) in analytics tools, you may need to implement surveys or add fields to forms on your website to gather this specific information directly from your visitors.

    How to build website segmentation analytics

    With Matomo, you can create a variety of segments to divide your website visitors into different groups. Matomo’s Segments allows you to view segmentation analytics on subsets of your audience, like :

    • The device they used while visiting your site
    • What channel they entered your site from
    • What country they are located
    • Whether or not they visited a key page of your website
    • And more

    While it’s important to collect general data on every visitor you have to your website, a key to website growth is understanding each type of visitor you have.

    For example, here’s a screenshot of how you can segment all of your website’s visitors from New Zealand :

    Matomo Dashboard of Segmentation by Country

    The criteria you use to define these segments are based on the data collected within your web analytics platform.

    Here are some popular ways you can create some common themes on Matomo that can be used to create segments :

    Visit based segments

    Create segments in Matomo based on visitors’ patterns. 

    For example :

    • Do returning visitors show different traits than first-time visitors ?
    • Do people who arrive on your blog experience your website differently than those arriving on a landing page ?

    This information can inform your content strategy, user interface design and marketing efforts.

    Demographic segments

    Create segments in Matomo based on people’s demographics. 

    For example :

    • User’s browser language
    • Location

    This can enable you to tailor your approach to specific demographics, improving the performance of your marketing campaigns.

    Technographic segments

    Create segments in Matomo based on people’s technographics. 

    For example :

    • Web browser being used (i.e., Chrome, Safari, Firefox, etc.)
    • Device type (i.e., smartphone, tablet, desktop)

    This can inform how to optimise your website based on users’ technology preferences, enhancing the effectiveness of your website.

    Interaction based segments

    Create segments in Matomo based on interactions. 

    For example :

    • Events (i.e., when someone clicks a specific URL on your website)
    • Goals (i.e., when someone stays on your site for a certain period)

    Insights from this can empower you to fine-tune your content and user experience for increasing conversion rates.

    Visitor Profile in Matomo
    Visitor profile view in Matomo with behavioural, location and technographic insights

    Campaign-based segments

    Create segments in Matomo based on campaigns. 

    For example :

    • Visitors arriving from specific traffic sources
    • Visitors arriving from specific advertising campaigns

    With these insights, you can assess the performance of your marketing efforts, optimise your ad spend and make data-driven decisions to enhance your campaigns for better results.

    Ecommerce segments

    Create segments in Matomo based on ecommerce

    For example :

    • Visitors who purchased vs. those who didn’t
    • Visitors who purchased a specific product

    This allows you to refine your website and marketing strategy for increased conversions and revenue.

    Leverage Matomo for your segmentation analytics

    By now, you can see the power of segmentation analytics and how they can be used to understand your customers and website visitors better. By breaking down your audience into groups, you’ll be able to gain insights into those segments to know how to serve them better with improved messaging and relevant products.

    If you’re ready to begin using segmentation analytics on your website, try Matomo. Start your 21-day free trial now — no credit card required.

    Matomo is an ideal choice for marketers looking for an easy-to-use, out-of-the-box web analytics solution that delivers accurate insights while keeping privacy and compliance at the forefront.

  • How to Stream RTP (IP camera) Into React App setup

    10 novembre 2024, par sharon2469

    I am trying to transfer a live broadcast from an IP camera or any other broadcast coming from an RTP/RTSP source to my REACT application. BUT MUST BE LIVE

    


    My setup at the moment is :

    


    IP Camera -> (RTP) -> FFmpeg -> (udp) -> Server(nodeJs) -> (WebRTC) -> React app

    


    In the current situation, There is almost no delay, but there are some things here that I can't avoid and I can't understand why, and here is my question :

    


    1) First, is the SETUP even correct and this is the only way to Stream RTP video in Web app ?

    


    2) Is it possible to avoid re-encode the stream , RTP transmission necessarily comes in H.264, hence I don't really need to execute the following command :

    


        return spawn('ffmpeg', [
    '-re',                              // Read input at its native frame rate Important for live-streaming
    '-probesize', '32',                 // Set probing size to 32 bytes (32 is minimum)
    '-analyzeduration', '1000000',      // An input duration of 1 second
    '-c:v', 'h264',                     // Video codec of input video
    '-i', 'rtp://238.0.0.2:48888',      // Input stream URL
    '-map', '0:v?',                     // Select video from input stream
    '-c:v', 'libx264',                  // Video codec of output stream
    '-preset', 'ultrafast',             // Faster encoding for lower latency
    '-tune', 'zerolatency',             // Optimize for zero latency
    // '-s', '768x480',                    // Adjust the resolution (experiment with values)
    '-f', 'rtp', `rtp://127.0.0.1:${udpPort}` // Output stream URL
]);


    


    As you can se in this command I re-encode to libx264, But if I set FFMPEG a parameter '-c:v' :'copy' instead of '-c:v', 'libx264' then FFMPEG throw an error says : that it doesn't know how to encode h264 and only knows what is libx264-> Basically, I want to stop the re-encode because there is really no need for it, because the stream is already encoded to H264. Are there certain recommendations that can be made ?

    


    3) I thought about giving up the FFMPEG completely, but the RTP packets arrive at a size of 1200+ BYTES when WEBRTC is limited to up to 1280 BYTE. Is there a way to manage these sabotages without damaging the video and is it to enter this world ? I guess there is the whole story with the JITTER BUFFER here

    


    This is my server side code (THIS IS JUST A TEST CODE)

    


    import {
    MediaStreamTrack,
    randomPort,
    RTCPeerConnection,
    RTCRtpCodecParameters,
    RtpPacket,
} from 'werift'
import {Server} from "ws";
import {createSocket} from "dgram";
import {spawn} from "child_process";
import LoggerFactory from "./logger/loggerFactory";

//

const log = LoggerFactory.getLogger('ServerMedia')

// Websocket server -> WebRTC
const serverPort = 8888
const server = new Server({port: serverPort});
log.info(`Server Media start om port: ${serverPort}`);

// UDP server -> ffmpeg
const udpPort = 48888
const udp = createSocket("udp4");
// udp.bind(udpPort, () => {
//     udp.addMembership("238.0.0.2");
// })
udp.bind(udpPort)
log.info(`UDP port: ${udpPort}`)


const createFFmpegProcess = () => {
    log.info(`Start ffmpeg process`)
    return spawn('ffmpeg', [
        '-re',                              // Read input at its native frame rate Important for live-streaming
        '-probesize', '32',                 // Set probing size to 32 bytes (32 is minimum)
        '-analyzeduration', '1000000',      // An input duration of 1 second
        '-c:v', 'h264',                     // Video codec of input video
        '-i', 'rtp://238.0.0.2:48888',      // Input stream URL
        '-map', '0:v?',                     // Select video from input stream
        '-c:v', 'libx264',                  // Video codec of output stream
        '-preset', 'ultrafast',             // Faster encoding for lower latency
        '-tune', 'zerolatency',             // Optimize for zero latency
        // '-s', '768x480',                    // Adjust the resolution (experiment with values)
        '-f', 'rtp', `rtp://127.0.0.1:${udpPort}` // Output stream URL
    ]);

}

let ffmpegProcess = createFFmpegProcess();


const attachFFmpegListeners = () => {
    // Capture standard output and print it
    ffmpegProcess.stdout.on('data', (data) => {
        log.info(`FFMPEG process stdout: ${data}`);
    });

    // Capture standard error and print it
    ffmpegProcess.stderr.on('data', (data) => {
        console.error(`ffmpeg stderr: ${data}`);
    });

    // Listen for the exit event
    ffmpegProcess.on('exit', (code, signal) => {
        if (code !== null) {
            log.info(`ffmpeg process exited with code ${code}`);
        } else if (signal !== null) {
            log.info(`ffmpeg process killed with signal ${signal}`);
        }
    });
};


attachFFmpegListeners();


server.on("connection", async (socket) => {
    const payloadType = 96; // It is a numerical value that is assigned to each codec in the SDP offer/answer exchange -> for H264
    // Create a peer connection with the codec parameters set in advance.
    const pc = new RTCPeerConnection({
        codecs: {
            audio: [],
            video: [
                new RTCRtpCodecParameters({
                    mimeType: "video/H264",
                    clockRate: 90000, // 90000 is the default value for H264
                    payloadType: payloadType,
                }),
            ],
        },
    });

    const track = new MediaStreamTrack({kind: "video"});


    udp.on("message", (data) => {
        console.log(data)
        const rtp = RtpPacket.deSerialize(data);
        rtp.header.payloadType = payloadType;
        track.writeRtp(rtp);
    });

    udp.on("error", (err) => {
        console.log(err)

    });

    udp.on("close", () => {
        console.log("close")
    });

    pc.addTransceiver(track, {direction: "sendonly"});

    await pc.setLocalDescription(await pc.createOffer());
    const sdp = JSON.stringify(pc.localDescription);
    socket.send(sdp);

    socket.on("message", (data: any) => {
        if (data.toString() === 'resetFFMPEG') {
            ffmpegProcess.kill('SIGINT');
            log.info(`FFMPEG process killed`)
            setTimeout(() => {
                ffmpegProcess = createFFmpegProcess();
                attachFFmpegListeners();
            }, 5000)
        } else {
            pc.setRemoteDescription(JSON.parse(data));
        }
    });
});


    


    And this fronted :

    


    &#xA;&#xA;&#xA;    &#xA;    &#xA;    <code class="echappe-js">&lt;script&amp;#xA;            crossorigin&amp;#xA;            src=&quot;https://unpkg.com/react@16/umd/react.development.js&quot;&amp;#xA;    &gt;&lt;/script&gt;&#xA;    &lt;script&amp;#xA;            crossorigin&amp;#xA;            src=&quot;https://unpkg.com/react-dom@16/umd/react-dom.development.js&quot;&amp;#xA;    &gt;&lt;/script&gt;&#xA;    &lt;script&amp;#xA;            crossorigin&amp;#xA;            src=&quot;https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js&quot;&amp;#xA;    &gt;&lt;/script&gt;&#xA;    &lt;script src=&quot;https://cdn.jsdelivr.net/npm/babel-regenerator-runtime@6.5.0/runtime.min.js&quot;&gt;&lt;/script&gt;&#xA;&#xA;&#xA;
    &#xA;

    &#xA;

    &#xA;&lt;script type=&quot;text/babel&quot;&gt;&amp;#xA;    let rtc;&amp;#xA;&amp;#xA;    const App = () =&gt; {&amp;#xA;        const [log, setLog] = React.useState([]);&amp;#xA;        const videoRef = React.useRef();&amp;#xA;        const socket = new WebSocket(&quot;ws://localhost:8888&quot;);&amp;#xA;        const [peer, setPeer] = React.useState(null); // Add state to keep track of the peer connection&amp;#xA;&amp;#xA;        React.useEffect(() =&gt; {&amp;#xA;            (async () =&gt; {&amp;#xA;                await new Promise((r) =&gt; (socket.onopen = r));&amp;#xA;                console.log(&quot;open websocket&quot;);&amp;#xA;&amp;#xA;                const handleOffer = async (offer) =&gt; {&amp;#xA;                    console.log(&quot;new offer&quot;, offer.sdp);&amp;#xA;&amp;#xA;                    const updatedPeer = new RTCPeerConnection({&amp;#xA;                        iceServers: [],&amp;#xA;                        sdpSemantics: &quot;unified-plan&quot;,&amp;#xA;                    });&amp;#xA;&amp;#xA;                    updatedPeer.onicecandidate = ({ candidate }) =&gt; {&amp;#xA;                        if (!candidate) {&amp;#xA;                            const sdp = JSON.stringify(updatedPeer.localDescription);&amp;#xA;                            console.log(sdp);&amp;#xA;                            socket.send(sdp);&amp;#xA;                        }&amp;#xA;                    };&amp;#xA;&amp;#xA;                    updatedPeer.oniceconnectionstatechange = () =&gt; {&amp;#xA;                        console.log(&amp;#xA;                            &quot;oniceconnectionstatechange&quot;,&amp;#xA;                            updatedPeer.iceConnectionState&amp;#xA;                        );&amp;#xA;                    };&amp;#xA;&amp;#xA;                    updatedPeer.ontrack = (e) =&gt; {&amp;#xA;                        console.log(&quot;ontrack&quot;, e);&amp;#xA;                        videoRef.current.srcObject = e.streams[0];&amp;#xA;                    };&amp;#xA;&amp;#xA;                    await updatedPeer.setRemoteDescription(offer);&amp;#xA;                    const answer = await updatedPeer.createAnswer();&amp;#xA;                    await updatedPeer.setLocalDescription(answer);&amp;#xA;&amp;#xA;                    setPeer(updatedPeer);&amp;#xA;                };&amp;#xA;&amp;#xA;                socket.onmessage = (ev) =&gt; {&amp;#xA;                    const data = JSON.parse(ev.data);&amp;#xA;                    if (data.type === &quot;offer&quot;) {&amp;#xA;                        handleOffer(data);&amp;#xA;                    } else if (data.type === &quot;resetFFMPEG&quot;) {&amp;#xA;                        // Handle the resetFFMPEG message&amp;#xA;                        console.log(&quot;FFmpeg reset requested&quot;);&amp;#xA;                    }&amp;#xA;                };&amp;#xA;            })();&amp;#xA;        }, []); // Added socket as a dependency to the useEffect hook&amp;#xA;&amp;#xA;        const sendRequestToResetFFmpeg = () =&gt; {&amp;#xA;            socket.send(&quot;resetFFMPEG&quot;);&amp;#xA;        };&amp;#xA;&amp;#xA;        return (&amp;#xA;            &lt;div&gt;&amp;#xA;                Video: &amp;#xA;                &lt;video ref={videoRef} autoPlay muted /&gt;&amp;#xA;                &lt;button onClick={() =&gt; sendRequestToResetFFmpeg()}&gt;Reset FFMPEG&lt;/button&gt;&amp;#xA;            &lt;/div&gt;&amp;#xA;        );&amp;#xA;    };&amp;#xA;&amp;#xA;    ReactDOM.render(&lt;App /&gt;, document.getElementById(&quot;app1&quot;));&amp;#xA;&lt;/script&gt;&#xA;&#xA;&#xA;

    &#xA;

  • closed (H264 track 1 is not valid : sprop-parameter-sets is missing (96 packetization-mode=1)

    8 janvier 2024, par MMingY

    I used FFmpeg6.1 to stream RTSP, but I received the following errors on the server :

    &#xA;

    &#xA;

    closed (H264 track 1 is not valid : sprop-parameter-sets is missing (96 packetization-mode=1),client:Error occurred when opening output Server returned 400 Bad Request.

    &#xA;

    &#xA;

    #include &#xA;#include &#xA;#include &#xA;&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libavutil></libavutil>opt.h>&#xA;#include <libavutil></libavutil>imgutils.h>&#xA;#include <libavutil></libavutil>time.h>&#xA;&#xA;static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,&#xA;                   AVFormatContext *outFormatCtx) {&#xA;    int ret;&#xA;&#xA;    /* send the frame to the encoder */&#xA;    if (frame)&#xA;        printf("Send frame %3"PRId64"\n", frame->pts);&#xA;&#xA;    ret = avcodec_send_frame(enc_ctx, frame);&#xA;    if (ret &lt; 0) {&#xA;        char errbuf[AV_ERROR_MAX_STRING_SIZE];&#xA;        av_strerror(ret, errbuf, AV_ERROR_MAX_STRING_SIZE);&#xA;        fprintf(stderr, "Error sending a frame for encoding ,%s\n", errbuf);&#xA;        exit(1);&#xA;    }&#xA;&#xA;    while (ret >= 0) {&#xA;        ret = avcodec_receive_packet(enc_ctx, pkt);&#xA;        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)&#xA;            return;&#xA;        else if (ret &lt; 0) {&#xA;            fprintf(stderr, "Error during encoding\n");&#xA;            exit(1);&#xA;        }&#xA;&#xA;        printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);&#xA;        av_write_frame(outFormatCtx, pkt); // Write the packet to the RTMP stream&#xA;        av_packet_unref(pkt);&#xA;    }&#xA;}&#xA;&#xA;int main(int argc, char **argv) {&#xA;    av_log_set_level(AV_LOG_DEBUG);&#xA;    const char *rtmp_url, *codec_name;&#xA;    const AVCodec *codec;&#xA;    AVCodecContext *codecContext = NULL;&#xA;    int i, ret, x, y;&#xA;    AVFormatContext *outFormatCtx;&#xA;    AVStream *st;&#xA;    AVFrame *frame;&#xA;    AVPacket *pkt;&#xA;    uint8_t endcode[] = {0, 0, 1, 0xb7};&#xA;&#xA;    if (argc &lt;= 3) {&#xA;        fprintf(stderr, "Usage: %s <rtmp url="url"> <codec>\n", argv[0]);&#xA;        exit(0);&#xA;    }&#xA;    rtmp_url = argv[1];&#xA;    codec_name = argv[2];&#xA;    avformat_network_init();&#xA;    /* find the mpeg1video encoder */&#xA;//    codec = avcodec_find_encoder_by_name(codec_name);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_MPEG4);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_VP9);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_MPEG2VIDEO);&#xA;    codec = avcodec_find_encoder(AV_CODEC_ID_H264);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_AV1);&#xA;//    codec = avcodec_find_encoder(AV_CODEC_ID_H265);&#xA;    if (!codec) {&#xA;        fprintf(stderr, "Codec &#x27;%s&#x27; not found\n", codec_name);&#xA;        exit(1);&#xA;    }&#xA;    codecContext = avcodec_alloc_context3(codec);&#xA;    if (!codecContext) {&#xA;        fprintf(stderr, "Could not allocate video codec context\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* ... (rest of the setup code) ... */&#xA;/* put sample parameters */&#xA;    codecContext->bit_rate = 400000;&#xA;    /* resolution must be a multiple of two */&#xA;    codecContext->width = 352;&#xA;    codecContext->height = 288;&#xA;    /* frames per second */&#xA;    codecContext->time_base = (AVRational) {1, 25};&#xA;    codecContext->framerate = (AVRational) {25, 1};&#xA;&#xA;    /* emit one intra frame every ten frames&#xA;     * check frame pict_type before passing frame&#xA;     * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I&#xA;     * then gop_size is ignored and the output of encoder&#xA;     * will always be I frame irrespective to gop_size&#xA;     */&#xA;    codecContext->gop_size = 10;&#xA;    codecContext->max_b_frames = 1;&#xA;    codecContext->pix_fmt = AV_PIX_FMT_YUV420P;&#xA;&#xA;&#xA;&#xA;    /* Open the RTSP output */&#xA;//    const AVOutputFormat *ofmt = av_guess_format("tcp", NULL, NULL);&#xA;    const AVOutputFormat *ofmt = av_guess_format("rtsp", rtmp_url, NULL);&#xA;//    const AVOutputFormat *ofmt = av_guess_format("flv", NULL, NULL);&#xA;//    const AVOutputFormat *ofmt = av_guess_format("rtmp", NULL, NULL);&#xA;//    const AVOutputFormat *ofmt = av_guess_format("mpegts", NULL, NULL);&#xA;//    const AVOutputFormat *ofmt = av_guess_format("mp4", NULL, NULL);&#xA;    if (!ofmt) {&#xA;        fprintf(stderr, "Could not find output format\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* Allocate the output context */&#xA;&#xA;/*    outFormatCtx = avformat_alloc_context();&#xA;    if (!outFormatCtx) {&#xA;        fprintf(stderr, "Could not allocate output context\n");&#xA;        exit(1);&#xA;    }*/&#xA;&#xA;    // 打开输出  这个会导致outFormatCtx 中的stream 为空,并且产生这个问题[rtsp @ 00000204f6218b80] No streams to mux were specified&#xA;    if (avformat_alloc_output_context2(&amp;outFormatCtx, ofmt, "rtsp", rtmp_url) != 0) {&#xA;        fprintf(stderr, "Could not allocate output context\n");&#xA;        return 1;&#xA;    }&#xA;&#xA;&#xA;    outFormatCtx->oformat = ofmt;&#xA;    outFormatCtx->url = av_strdup(rtmp_url);&#xA;&#xA;    /* Add a video stream */&#xA;    st = avformat_new_stream(outFormatCtx, codec);&#xA;    if (!st) {&#xA;        fprintf(stderr, "Could not allocate stream\n");&#xA;        exit(1);&#xA;    }&#xA;    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;&#xA;    st->codecpar->codec_id = codec->id;&#xA;    st->codecpar->width = 352;&#xA;    st->codecpar->height = 288;&#xA;    st->codecpar->format = AV_PIX_FMT_YUV420P;&#xA;//    st->codecpar = c;&#xA;//    st->codecpar->format = AV_PIX_FMT_YUV420P;&#xA;    // Set video stream parameters&#xA;//    st->codecpar->framerate = (AVRational) {25, 1};&#xA;//    st->id=outFormatCtx->nb_streams-1;&#xA;    /* Set the output URL */&#xA;    av_dict_set(&amp;outFormatCtx->metadata, "url", rtmp_url, 0);&#xA;&#xA;&#xA;    pkt = av_packet_alloc();&#xA;    if (!pkt)&#xA;        exit(1);&#xA;&#xA;&#xA;    if (codec->id == AV_CODEC_ID_H264)&#xA;        av_opt_set(codecContext->priv_data, "preset", "slow", 0);&#xA;&#xA;    AVDictionary *opt = NULL;&#xA;/*    av_dict_set(&amp;opt, "rtsp_transport", "udp", 0);&#xA;    av_dict_set(&amp;opt, "announce_port", "1935", 0);&#xA;    av_dict_set(&amp;opt, "enable-protocol", "rtsp", 0);&#xA;    av_dict_set(&amp;opt, "protocol_whitelist", "file,udp,tcp,rtp,rtsp", 0);&#xA;    av_dict_set(&amp;opt, "enable-protocol", "rtp", 0);&#xA;    av_dict_set(&amp;opt, "enable-protocol", "rtsp", 0);&#xA;    av_dict_set(&amp;opt, "enable-protocol", "udp", 0);&#xA;    av_dict_set(&amp;opt, "enable-muxer", "rtsp", 0);&#xA;    av_dict_set(&amp;opt, "enable-muxer", "rtp", 0);*/&#xA;    av_dict_set(&amp;opt, "rtsp_transport", "tcp", 0);&#xA;    av_dict_set(&amp;opt, "stimeout", "2000000", 0);&#xA;    av_dict_set(&amp;opt, "max_delay", "500000", 0);&#xA;    av_dict_set(&amp;opt, "sprop-parameter-sets", "asdgasdfs", AV_DICT_APPEND);&#xA;    /* open it */&#xA;    ret = avcodec_open2(codecContext, codec, &amp;opt);&#xA;    if (ret &lt; 0) {&#xA;        fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));&#xA;        exit(1);&#xA;    }&#xA;/*    // 打开RTSP输出URL  微软AI给出的代码&#xA;    if (!(outFormatCtx->oformat->flags &amp; AVFMT_NOFILE)) {&#xA;        int ret = avio_open(&amp;outFormatCtx->pb, rtmp_url, AVIO_FLAG_WRITE);&#xA;        if (ret &lt; 0) {&#xA;//            std::cerr &lt;&lt; "Could not open output URL " &lt;&lt; out_url &lt;&lt; std::endl;&#xA;            fprintf(stderr, "Could not open output URL  %s\n", av_err2str(ret));&#xA;            return -1;&#xA;        }&#xA;    }*/&#xA;&#xA;    avcodec_parameters_to_context(codecContext, st->codecpar);&#xA;&#xA;/*    AVDictionary *options = NULL;&#xA;    av_dict_set(&amp;options, "rtsp_transport", "tcp", 0);&#xA;    av_dict_set(&amp;options, "stimeout", "2000000", 0);&#xA;    av_dict_set(&amp;options, "max_delay", "500000", 0);&#xA;    // 初始化输出&#xA;    av_dict_set(&amp;options, "rtsp_transport", "tcp", 0);&#xA;//设置 接收包间隔最大延迟,微秒&#xA;    av_dict_set(&amp;options, "max_delay", "200000", 0);&#xA;// rtmp、rtsp延迟控制到最小&#xA;    av_dict_set(&amp;options, "fflags", "nobuffer", 0);&#xA;// 在进行网络操作时允许的最大等待时间。5秒&#xA;    av_dict_set(&amp;options, "timeout", "5000000", 0);&#xA;//设置 阻塞超时,否则可能在流断开时连接发生阻塞,微秒&#xA;    av_dict_set(&amp;options, "stimeout", "3000000", 0);&#xA;//设置 find_stream_info 最大时长,微秒&#xA;    av_dict_set(&amp;options, "analyzeduration", "1000000", 0);*/&#xA;    av_dict_set(&amp;opt, "preset", "medium", 0);&#xA;    av_dict_set(&amp;opt, "tune", "zerolatency", 0);&#xA;    av_dict_set(&amp;opt, "profile", "baseline", 0);&#xA;    av_dump_format(outFormatCtx, 0, rtmp_url, 1);&#xA;&#xA;    if (avformat_init_output(outFormatCtx, &amp;opt) != 0) {&#xA;        fprintf(stderr, "Error initializing output\n");&#xA;        return 1;&#xA;    }&#xA;    if (!(ofmt->flags &amp; AVFMT_NOFILE)) {&#xA;        ret = avio_open(&amp;outFormatCtx->pb, rtmp_url, AVIO_FLAG_WRITE);&#xA;        if (ret &lt; 0) {&#xA;            fprintf(stderr, "Could not open output file &#x27;%s&#x27;", rtmp_url);&#xA;            exit(1);&#xA;        }&#xA;    }&#xA;    /*   这种方式修改没有效果,无法添加修改SDP&#xA;     * av_dict_set(&amp;st->metadata, "title", "Cool video", 0);&#xA;       av_dict_set(&amp;st->metadata, "Content-Base", " rtsp://10.45.12.141/h264/ch1/main/av_stream/", 0);&#xA;       av_dict_set(&amp;st->metadata, "sprop-parameter-sets", "sdsfwedeo", 0);*/&#xA;    AVCodecParameters *codecParams = st->codecpar;&#xA;    const char *spropParameterSets = "Z0IACpZTBYmI,aMlWsA==";  // 替换为实际的sprop-parameter-sets值&#xA;    av_dict_set(&amp;st->metadata, "sprop-parameter-sets", spropParameterSets, 0);&#xA;    avcodec_parameters_to_context(codecContext, st->codecpar);&#xA;    AVFormatContext *avFormatContext[1];&#xA;    avFormatContext[0] = outFormatCtx;&#xA;    char spd[2048];&#xA;    av_sdp_create(avFormatContext, 1, spd, sizeof(spd));&#xA;    printf("%s\n", spd);&#xA;/*    ret = avio_open(&amp;outFormatCtx->pb, rtmp_url, AVIO_FLAG_WRITE);&#xA;    if (ret &lt; 0) {&#xA;        fprintf(stderr, "Could not open output ,%s\n", av_err2str(ret));&#xA;        exit(1);&#xA;    }*/&#xA;&#xA;/*// 设置 H264 参数&#xA;    AVDictionary *params = NULL;&#xA;    av_dict_set(&amp;params, "profile", "main", 0);&#xA;    av_dict_set(&amp;params, "level", "3.1", 0);&#xA;&#xA;// 获取 `sprop-parameter-sets` 参数&#xA;    AVPacket *extradata = av_packet_alloc();&#xA;//    avcodec_parameters_from_context(extradata->data, codecContext);&#xA;&#xA;// 获取 `sprop-parameter-sets` 参数的大小&#xA;    int sprop_parameter_sets_size = extradata->size;&#xA;&#xA;// 释放资源&#xA;    av_packet_free(&amp;extradata);&#xA;&#xA;// 设置 `sprop-parameter-sets` 参数&#xA;    uint8_t *sprop_parameter_sets = extradata->data;&#xA;    codecContext->extradata = sprop_parameter_sets;&#xA;    codecContext->extradata_size = sprop_parameter_sets_size;*/&#xA;&#xA;    /* Write the header */&#xA;//    ret = avformat_write_header(outFormatCtx, NULL);&#xA;    ret = avformat_write_header(outFormatCtx, &amp;opt);&#xA;    if (ret != 0) {&#xA;        fprintf(stderr, "Error occurred when opening output %s\n", av_err2str(ret));&#xA;        exit(1);&#xA;    }&#xA;&#xA;    frame = av_frame_alloc();&#xA;    if (!frame) {&#xA;        fprintf(stderr, "Could not allocate video frame\n");&#xA;        exit(1);&#xA;    }&#xA;//    frame->format = c->pix_fmt;&#xA;//    frame->format = AV_PIX_FMT_YUV420P;&#xA;    frame->format = 0;&#xA;    frame->width = codecContext->width;&#xA;    frame->height = codecContext->height;&#xA;&#xA;    ret = av_frame_get_buffer(frame, 0);&#xA;    if (ret &lt; 0) {&#xA;        fprintf(stderr, "Could not allocate the video frame data ,%s\n", av_err2str(ret));&#xA;        exit(1);&#xA;    }&#xA;&#xA;    /* encode 1 second of video */&#xA;    for (i = 0; i &lt; 2500; i&#x2B;&#x2B;) {&#xA;        /* ... (rest of the encoding loop) ... */&#xA;        fflush(stdout);&#xA;&#xA;        /* make sure the frame data is writable */&#xA;        ret = av_frame_make_writable(frame);&#xA;        if (ret &lt; 0)&#xA;            exit(1);&#xA;&#xA;        /* prepare a dummy image */&#xA;        /* Y */&#xA;        for (y = 0; y &lt; codecContext->height; y&#x2B;&#x2B;) {&#xA;            for (x = 0; x &lt; codecContext->width; x&#x2B;&#x2B;) {&#xA;                frame->data[0][y * frame->linesize[0] &#x2B; x] = x &#x2B; y &#x2B; i * 3;&#xA;            }&#xA;        }&#xA;&#xA;        /* Cb and Cr */&#xA;        for (y = 0; y &lt; codecContext->height / 2; y&#x2B;&#x2B;) {&#xA;            for (x = 0; x &lt; codecContext->width / 2; x&#x2B;&#x2B;) {&#xA;                frame->data[1][y * frame->linesize[1] &#x2B; x] = 128 &#x2B; y &#x2B; i * 2;&#xA;                frame->data[2][y * frame->linesize[2] &#x2B; x] = 64 &#x2B; x &#x2B; i * 5;&#xA;            }&#xA;        }&#xA;&#xA;        frame->pts = i;&#xA;&#xA;        /* encode the image */&#xA;        encode(codecContext, frame, pkt, outFormatCtx);&#xA;    }&#xA;&#xA;    /* flush the encoder */&#xA;    encode(codecContext, NULL, pkt, outFormatCtx);&#xA;&#xA;    /* Write the trailer */&#xA;    av_write_trailer(outFormatCtx);&#xA;&#xA;    /* Close the output */&#xA;    avformat_free_context(outFormatCtx);&#xA;&#xA;    avcodec_free_context(&amp;codecContext);&#xA;    av_frame_free(&amp;frame);&#xA;    av_packet_free(&amp;pkt);&#xA;&#xA;    return 0;&#xA;}&#xA;</codec></rtmp>

    &#xA;

    I searched online for how to add "prop parameter sets", but I used their method but none of them worked. I also used WireShark to capture packets, but during the communication process, there was still no "prop parameter sets". Here is the method I tried :

    &#xA;

      AVDictionary *opt = NULL;&#xA; av_dict_set(&amp;opt, "sprop-parameter-sets", "asdgasdfs", 0);&#xA;

    &#xA;