Newest 'ffmpeg' Questions - Stack Overflow
Les articles publiés sur le site
-
Decoding the h.264 stream from a serial port
18 mars, par PeterI would like to know if there is a reliable way to decode an H.264 NAL stream coming through a serial port using software.
So far, I have managed to decode a single frame using a python script. In this script, I first write the incoming data to a file, and when the end-of-frame marker 00_00_00_01 appears, I display the frame using ffplay.
import serial import subprocess import os import time ser = serial.Serial('COM3', 115200, timeout=1) output_file = "output.264" # Variable to store the ffplay process ffplay_process = None # Open the file for writing in binary mode with open(output_file, "wb") as file: print("Writing bytes to output.264. Waiting for the end-of-frame marker 0x00000001.") buffer = bytearray() marker = b'\x00\x00\x00\x01' try: while True: if ser.in_waiting: # If there is data in the buffer data = ser.read(ser.in_waiting) # Read all available bytes buffer.extend(data) # Check if the end-of-frame marker is in the buffer while marker in buffer: index = buffer.index(marker) + len(marker) # Position after the marker frame = buffer[:index] # Extract the frame buffer = buffer[index:] # Keep the remaining data print(f"Frame recorded: {len(frame)} bytes") file.write(frame) # Write the frame to the file file.flush() # Force writing to disk # Close the ffplay window if it is already open if ffplay_process and ffplay_process.poll() is None: ffplay_process.terminate() ffplay_process.wait() # Wait for the process to terminate # Play the recorded frame, reopening the window ffplay_process = subprocess.Popen(["ffplay", "-f", "h264", "-i", output_file]) except KeyboardInterrupt: print("\nRecording stopped.") finally: # Close the serial port and the ffplay process ser.close()
However, each time a new end-of-frame marker is detected, the ffplay window closes and reopens to show the next frame. It will flicker when transferring the video. Is there a way to display the frames in the same window for seamless playback when streaming video?
Or is there a better approach or software that is more suited for this task? I do not know where to start, so I will be glad for any hints.
-
Problems encoding audio stream for RTMP server using ffmpeg libraries
18 mars, par Filipe JoséI am working on an C++ application that captures audio using miniaudio, and sends the data to a RTMP server running on nginx which will generate an HLS stream to be consumed by a web browser. I was successful in encoding the data and writing to an .flv file (which I believe to be the container for RTMP), and everything works out fine.
I've also tested the server by running the ffmpeg cli tool directly, and the RTMP server is generating the .m3u8 playlist file as well as the .ts files correctly.
The problem I'm having is that when I change the output on avio_open2() to use the RTMP server url instead of a file name, the HLS files are not being generated, even though I get logging information about a successful connection, and also see "Audio Data" packets being sent to the server and the respective ACK response when using Wireshark.
Is there anything that is conceptually different between encoding to a file or to a server when using the ffmpeg libav?
I have a class for the audio encoding:
AudioEncoder(int sampleRate){ av_log_set_level(AV_LOG_DEBUG); m_formatContext = avformat_alloc_context(); const AVOutputFormat* outputFormat = av_guess_format("flv", NULL, NULL); if (!outputFormat) { std::cerr << "Could not find aac output format" << std::endl; exit(-1); } m_formatContext->oformat = outputFormat; result = avio_open2(&m_ioContext, "rtmp://localhost/live/test",AVIO_FLAG_WRITE, NULL, NULL); if( result < 0){ std::cerr << "Could not open output stream: " << error_string(result) << std::endl; exit(-1); } m_formatContext->pb = m_ioContext; const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_AAC); if(!codec){ std::cerr << "Codec not found." << std::endl; exit(-1); } m_codecContext = avcodec_alloc_context3(codec); if (!m_codecContext) { std::cerr << "Could not alloc codec context" << std::endl; exit(-1); } AVChannelLayout layout; av_channel_layout_default(&layout, 1); m_codecContext->sample_fmt = AV_SAMPLE_FMT_FLTP; m_codecContext->bit_rate = 128000; m_codecContext->sample_rate = sampleRate; m_codecContext->ch_layout = layout; m_avStream = avformat_new_stream(m_formatContext, codec); if (!m_avStream) { std::cerr << "Could not create stream." << std::endl; exit(-1); } result = avcodec_parameters_from_context(m_avStream->codecpar, m_codecContext); if ( result < 0) { std::cerr << "Failed to copy codec parameters to stream: " << error_string(result) << std::endl; exit(-1); } m_avStream->time_base = AVRational{1, m_codecContext->sample_rate}; result = avcodec_open2(m_codecContext, codec, NULL); if ( result < 0) { std::cerr << "Failed to open codec: "<< error_string(result) << std::endl; exit(-1); } result = avformat_write_header(m_formatContext, NULL); if ( result < 0) { std::cerr << "Failed to write format header: "<< error_string(result) << std::endl; exit(-1); } }
And an Encode function that is called by miniaudio:
void Encode(const void* data, unsigned int frames){ AVPacket* packet = av_packet_alloc(); if (!packet) { std::cerr << "Error allocating packet" << std::endl; return; } AVFrame* frame = av_frame_alloc(); if (!frame) { std::cerr << "Error allocating frame" << std::endl; av_packet_free(&packet); return; } frame->format = m_codecContext->sample_fmt; frame->ch_layout = m_codecContext->ch_layout; frame->sample_rate = m_codecContext -> sample_rate; frame->nb_samples = frames; if (frames) { int result = av_frame_get_buffer(frame, 0); if ( result < 0) { std::cerr << "Error allocating frame buffer: " << error_string(result) << std::endl; av_frame_free(&frame); av_packet_free(&packet); return; } } frame->data[0] = (uint8_t*)data; int result = avcodec_send_frame(m_codecContext, frame); if (result < 0) { std::cerr << "Error sending frame to encoder: " << error_string(result) << std::endl; } result = avcodec_receive_packet(m_codecContext, packet); if (result == AVERROR(EAGAIN) || result == AVERROR_EOF) { std::cout << "EAGAIN" << std::endl; // If we get AVERROR_EAGAIN, the encoder needs more data, so we'll return and try again later av_frame_free(&frame); av_packet_free(&packet); return; } else if (result < 0) { std::cerr << "Error receiving packet from encoder: " << error_string(result) << std::endl; av_frame_free(&frame); av_packet_free(&packet); return; } else { packet->stream_index = m_avStream->index; packet->pts = av_rescale_q(frames, AVRational{1, m_codecContext->sample_rate}, m_avStream->time_base); packet->dts = packet->pts; packet->duration = av_rescale_q(1024, AVRational{1, m_codecContext->sample_rate}, m_avStream->time_base); result = av_write_frame(m_formatContext, packet); if ( result < 0) { std::cerr << "Error writing frame: " << error_string(result) << std::endl; } } //Clean up resources av_frame_free(&frame); av_packet_unref(packet); av_packet_free(&packet); }
On a final note, I have been able to stream to a TCP server developed in Golang using ADTS as the container and the same method, but I've decided to delegate the task to Nginx.
-
why mpd file contain same resolution AdaptationSet
18 mars, par Jahid Hasan Antorthis is the code that i used. this code create a minifest.mpd file, with the same resolution AdaptationSet set
const createCourse = async (req: Request, res: Response, next: NextFunction) => { try { const VIDEO_STORAGE_PATH = path.join(__dirname, "../../public/uploads").replace(/\\/g, "/"); const videoId = req.body.videoId; const inputPath = path.join(VIDEO_STORAGE_PATH, "original", `${videoId}.mp4`).replace(/\\/g, "/"); const outputDir = path.join(VIDEO_STORAGE_PATH, "dash", videoId).replace(/\\/g, "/"); if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } if (!ffmpegStatic) { return next(new Error("❌ ffmpegStatic path is null")); } ffmpeg.setFfmpegPath(ffmpegStatic); const qualities = [ { resolution: "1280x720", bitrate: "1800k" }, { resolution: "854x480", bitrate: "1200k" }, { resolution: "640x360", bitrate: "800k" }, { resolution: "426x240", bitrate: "400k" } ]; const outputMpd = path.join(outputDir, "manifest.mpd").replace(/\\/g, "/"); // Create FFmpeg command let command = ffmpeg(inputPath) .output(outputMpd) .outputOptions([ '-f dash', // Output format '-seg_duration 4', // Segment duration in seconds '-window_size 10', // Number of segments in the manifest '-init_seg_name init-stream$RepresentationID$.webm', // Name for initialization segments '-media_seg_name chunk-stream$RepresentationID$-$Number%05d$.webm', // Name for media segments ]); // Add multiple resolutions qualities.forEach(({ resolution, bitrate }) => { console.log('esolution, bitrate :>> ', resolution, bitrate); command .outputOptions([ `-map 0:v`, // Map the video stream `-s ${resolution}`, // Set resolution `-b:v ${bitrate}`, // Set bitrate `-c:v libvpx-vp9`, // Use VP9 codec `-c:a libopus`, // Use Opus codec ]); }); command .on("end", () => { console.log(`🚀 Video processing complete: ${outputMpd}`); }) .on("error", (err) => { console.error("❌ ffmpeg error:", err); next(err); }) .run();
-
Error Installing mobile-ffmpeg-full-gpl (4.4.LTS) via CocoaPods - 404 Not Found
18 mars, par Muhammad AccuciaI am trying to
install mobile-ffmpeg-full-gpl
(4.4.LTS) in my iOS project usingCocoaPods
, but I am encountering a 404 error whenCocoaPods
attempts to download the framework.Here is the error message:
\[!\] Error installing mobile-ffmpeg-full-gpl \[!\] /usr/bin/curl -f -L -o /var/folders/78/lk7swzb97ml4dt3zd9grny0c0000gn/T/d20250201-6580-dtli8h/file.zip https://github.com/tanersener/mobile-ffmpeg/releases/download/v4.4.LTS/mobile-ffmpeg-full-gpl-4.4.LTS-ios-framework.zip --create-dirs --netrc-optional --retry 2 -A 'CocoaPods/1.15.2 cocoapods-downloader/2.1' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 9 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 curl: (56) The requested URL returned error: 404
It seems like the requested file is no longer available at the specified URL.
Checked the official GitHub releases page for
mobile-ffmpeg-full-gpl
(4.4.LTS), but I couldn't find the exact file. -
Decoding the h.264 stream from a COM port
18 mars, par PeterI would like to know if there is a reliable way to decode an H.264 NAL stream coming through a serial port using software.
So far, I have managed to decode a single frame using a python script. In this script, I first write the incoming data to a file, and when the end-of-frame marker 00_00_00_01 appears, I display the frame using ffplay.
import serial import subprocess import os import time ser = serial.Serial('COM3', 115200, timeout=1) output_file = "output.264" # Variable to store the ffplay process ffplay_process = None # Open the file for writing in binary mode with open(output_file, "wb") as file: print("Writing bytes to output.264. Waiting for the end-of-frame marker 0x00000001.") buffer = bytearray() marker = b'\x00\x00\x00\x01' try: while True: if ser.in_waiting: # If there is data in the buffer data = ser.read(ser.in_waiting) # Read all available bytes buffer.extend(data) # Check if the end-of-frame marker is in the buffer while marker in buffer: index = buffer.index(marker) + len(marker) # Position after the marker frame = buffer[:index] # Extract the frame buffer = buffer[index:] # Keep the remaining data print(f"Frame recorded: {len(frame)} bytes") file.write(frame) # Write the frame to the file file.flush() # Force writing to disk # Close the ffplay window if it is already open if ffplay_process and ffplay_process.poll() is None: ffplay_process.terminate() ffplay_process.wait() # Wait for the process to terminate # Play the recorded frame, reopening the window ffplay_process = subprocess.Popen(["ffplay", "-f", "h264", "-i", output_file]) except KeyboardInterrupt: print("\nRecording stopped.") finally: # Close the serial port and the ffplay process ser.close()
However, each time a new end-of-frame marker is detected, the ffplay window closes and reopens to show the next frame. It will flicker when transferring the video. Is there a way to display the frames in the same window for seamless playback when streaming video?
Or is there a better approach or software that is more suited for this task? I do not know where to start, so I will be glad for any hints.