
Recherche avancée
Autres articles (90)
-
Le profil des utilisateurs
12 avril 2011, parChaque utilisateur dispose d’une page de profil lui permettant de modifier ses informations personnelle. Dans le menu de haut de page par défaut, un élément de menu est automatiquement créé à l’initialisation de MediaSPIP, visible uniquement si le visiteur est identifié sur le site.
L’utilisateur a accès à la modification de profil depuis sa page auteur, un lien dans la navigation "Modifier votre profil" est (...) -
Configurer la prise en compte des langues
15 novembre 2010, parAccéder à la configuration et ajouter des langues prises en compte
Afin de configurer la prise en compte de nouvelles langues, il est nécessaire de se rendre dans la partie "Administrer" du site.
De là, dans le menu de navigation, vous pouvez accéder à une partie "Gestion des langues" permettant d’activer la prise en compte de nouvelles langues.
Chaque nouvelle langue ajoutée reste désactivable tant qu’aucun objet n’est créé dans cette langue. Dans ce cas, elle devient grisée dans la configuration et (...) -
XMP PHP
13 mai 2011, parDixit Wikipedia, XMP signifie :
Extensible Metadata Platform ou XMP est un format de métadonnées basé sur XML utilisé dans les applications PDF, de photographie et de graphisme. Il a été lancé par Adobe Systems en avril 2001 en étant intégré à la version 5.0 d’Adobe Acrobat.
Étant basé sur XML, il gère un ensemble de tags dynamiques pour l’utilisation dans le cadre du Web sémantique.
XMP permet d’enregistrer sous forme d’un document XML des informations relatives à un fichier : titre, auteur, historique (...)
Sur d’autres sites (10293)
-
FFMPEG Corrupt output remuxing MP4 (Using API in C) -First file OK, 2nd file onwards is not
25 janvier, par RichardPI have a simple application written in C - it takes the video from a RTSP camera and just writes to disk in 1 minute segments. The first file created works fine, plays on anlmost anything. The Second file does not play. Programatically, The trace shows they are the same code flows, but I cant seem to find where the problem is to allow the 2nd file to be play exactly the same as the first.


There are frames in the 2nd file but they are random. The second file is created EXACTLY the same way as the first.


Any help from a guru would be greatly appreciated.


EDIT : FIX - The output duration needs to be set before the trailer is written.


int actual_duration = (int)difftime(time(NULL), start_time);

for (int i = 0; i < output_ctx->nb_streams; i++) {
 output_ctx->streams[i]->duration = actual_duration * AV_TIME_BASE;
}

output_ctx->duration = actual_duration * AV_TIME_BASE;
printf("DURATION = %d\r\n",output_ctx->duration);

// Set the start_time for the output context
output_ctx->start_time = 0;

av_write_trailer(output_ctx);



Code flow


Open RTSP Stream 
A: Create File n context 
 Remux to file n 
 Wait for minute to change 
 Close File n context 
 increment n Goto A



Makefile


CC = gcc
CFLAGS = -Wall -g
LIBS = -lavformat -lavcodec -lavutil -lavdevice -lswscale -lavfilter -lavutil -lm -lz -lpthread

TARGET = rtsp_remux

all: $(TARGET)

$(TARGET): rtsp_remux.o
 $(CC) -o $(TARGET) rtsp_remux.o $(LIBS)

rtsp_remux.o: rtsp_remux.c
 $(CC) $(CFLAGS) -c rtsp_remux.c

clean:
 rm -f $(TARGET) rtsp_remux.o

.PHONY: all clean



rtsp_remux.c


#include <libavformat></libavformat>avformat.h>
#include <libavutil></libavutil>time.h>
#include 
#include 

#define OUTPUT_PREFIX "output"
#define OUTPUT_EXTENSION ".mp4"
#define MAX_FILES 4

int main(int argc, char *argv[]) {
 if (argc < 2) {
 fprintf(stderr, "Usage: %s <rtsp url="url">\n", argv[0]);
 return -1;
 }

 const char *rtsp_url = argv[1];
 AVFormatContext *input_ctx = NULL, *output_ctx = NULL;
 AVOutputFormat *output_fmt = NULL;
 AVPacket pkt;
 int ret, file_count = 0;
 char output_filename[1024];
 time_t current_time;
 struct tm *timeinfo;
 int rename_lock = 0;

 avformat_network_init();

 if ((ret = avformat_open_input(&input_ctx, rtsp_url, NULL, NULL)) < 0) {
 fprintf(stderr, "Could not open input file '%s'\n", rtsp_url);
 return -1;
 }

 if ((ret = avformat_find_stream_info(input_ctx, NULL)) < 0) {
 fprintf(stderr, "Failed to retrieve input stream information\n");
 return -1;
 }

 av_dump_format(input_ctx, 0, rtsp_url, 0);

 while (file_count < MAX_FILES) {
 snprintf(output_filename, sizeof(output_filename), "%s_%03d%s", OUTPUT_PREFIX, file_count, OUTPUT_EXTENSION);

 if ((ret = avformat_alloc_output_context2(&output_ctx, NULL, NULL, output_filename)) < 0) {
 fprintf(stderr, "Could not create output context\n");
 return -1;
 }

 output_fmt = output_ctx->oformat;

 for (int i = 0; i < input_ctx->nb_streams; i++) {
 AVStream *in_stream = input_ctx->streams[i];
 AVStream *out_stream = avformat_new_stream(output_ctx, NULL);
 if (!out_stream) {
 fprintf(stderr, "Failed allocating output stream\n");
 return -1;
 }

 if ((ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar)) < 0) {
 fprintf(stderr, "Failed to copy codec parameters\n");
 return -1;
 }
 out_stream->codecpar->codec_tag = 0;
 }

 if (!(output_fmt->flags & AVFMT_NOFILE)) {
 if ((ret = avio_open(&output_ctx->pb, output_filename, AVIO_FLAG_WRITE)) < 0) {
 fprintf(stderr, "Could not open output file '%s'\n", output_filename);
 return -1;
 }
 }

 if ((ret = avformat_write_header(output_ctx, NULL)) < 0) {
 fprintf(stderr, "Error occurred when opening output file\n");
 return -1;
 }

 while (1) {
 current_time = time(NULL);
 timeinfo = localtime(&current_time);

 if (timeinfo->tm_sec == 0 && !rename_lock) {
 rename_lock = 1;
 break;
 } else if (timeinfo->tm_sec != 0) {
 rename_lock = 0;
 }

 if ((ret = av_read_frame(input_ctx, &pkt)) < 0)
 break;

 AVStream *in_stream = input_ctx->streams[pkt.stream_index];
 AVStream *out_stream = output_ctx->streams[pkt.stream_index];

 pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
 pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
 pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
 pkt.pos = -1;

 if ((ret = av_interleaved_write_frame(output_ctx, &pkt)) < 0) {
 fprintf(stderr, "Error muxing packet\n");
 break;
 }

 av_packet_unref(&pkt);
 }

 av_write_trailer(output_ctx);

 if (!(output_fmt->flags & AVFMT_NOFILE))
 avio_closep(&output_ctx->pb);

 avformat_free_context(output_ctx);

 file_count++;
 }

 avformat_close_input(&input_ctx);
 avformat_network_deinit();

 return 0;
}
</rtsp>


I have tried changing to pointers, freeing and different things. I was expecting the 2nd file created to behave identically to the first.


-
Converting HLS Stream to stream supported by old radio
29 novembre 2024, par Alberto FaenzaI have an old internet radio that does not support HLS streams.
Therefore I cannot listen to my favourite radio at this url :
https://streamcdnf31-4c4b867c89244861ac216426883d1ad0.msvdn.net/radiodeejay/radiodeejay/master_ma.m3u8


I found a solution using a paid software https://minimradio.com/ which is based on minimserver and minimstreamer.


This solution works if I install mininmserver and minimstreamer on a local computer and use the internet radio to point to the converter stream but I will have to pay if I want to use this.


Checking the documentation of minimradio and ministreamer I can see the following :


*Some internet radios can play the previous AAC ADTS streams but can't play these new HLS streams
...


If the network stream URL points to an HLS .m3u8 master playlist or media playlist file, MinimStreamer reads this file and uses the HLS protocol to read the stream audio data and send it to the music player as a conventional HTTP stream. This makes the stream playable on music players that don't support the HLS protocol. The audio data in the stream must be encoded in AAC format.*
and not a single destination receiver I should use a streaming (broadcasting) server. What can I use to do that ?


My question is the following :
Is there a way to replicate what minimstreamer is doing using ffmpeg ?
I have tried this :




ffmpeg -re -i https://streamcdnf31-4c4b867c89244861ac216426883d1ad0.msvdn.net/radiodeejay/radiodeejay/master_ma.m3u8 -c copy -listen 1 -f mpegts http://192.168.1.9:10000




which is playing corrctly in local vlc on the same computer. But when I stop VLC is got this error in ffmpeg :


[https @ 00000291de047400] Cannot reuse HTTP connection for different host: StreamCdnG20-4c4b867c89244861ac216426883d1ad0.msvdn.net:-1 != 4c4b867c89244861ac216426883d1ad0.msvdn.net:-1
[hls @ 00000291dd96d140] keepalive request failed for 'https://4c4b867c89244861ac216426883d1ad0.msvdn.net/radiodeejay/radiodeejay/play1.m3u8' with error: 'Invalid argument' when parsing playlist
[hls @ 00000291dd96d140] Opening 'https://4c4b867c89244861ac216426883d1ad0.msvdn.net/radiodeejay/radiodeejay/play1.m3u8' for reading
[hls @ 00000291dd96d140] Skip ('#EXT-X-DISCONTINUITY-SEQUENCE:0')
[hls @ 00000291dd96d140] Skip ('#EXT-X-PROGRAM-DATE-TIME:2024-11-29T06:36:56.926Z')
[hls @ 00000291dd96d140] Skip ('#EXT-X-PROGRAM-DATE-TIME:2024-11-29T06:37:07.314Z')
[hls @ 00000291dd96d140] Skip ('#EXT-X-PROGRAM-DATE-TIME:2024-11-29T06:37:17.571Z')
[https @ 00000291de4e00c0] Opening 'https://StreamCdnG20-4c4b867c89244861ac216426883d1ad0.msvdn.net/radiodeejay/radiodeejay/20240722T095729_p1s_001086632.ts' for reading
[aost#0:0/copy @ 00000291de1c4f40] Error submitting a packet to the muxer: Error number -10054 occurred
 Last message repeated 1 times
[out#0/mpegts @ 00000291deaa7e40] Error muxing a packet
[out#0/mpegts @ 00000291deaa7e40] Task finished with error code: -10054 (Error number -10054 occurred)
[out#0/mpegts @ 00000291deaa7e40] Terminating thread with return code -10054 (Error number -10054 occurred)
[out#0/mpegts @ 00000291deaa7e40] Error writing trailer: Error number -10054 occurred
[http @ 00000291de8870c0] URL read error: Error number -10054 occurred
[out#0/mpegts @ 00000291deaa7e40] Error closing file: Error number -10054 occurred
[out#0/mpegts @ 00000291deaa7e40] video:0KiB audio:797KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 21.849292%
size= 971KiB time=00:00:50.98 bitrate= 156.0kbits/s speed=1.01x
Conversion failed!



And if I try to connect from my internet radio I immediately got this error :


[aost#0:0/copy @ 0000027081584a40] Error submitting a packet to the muxer: Error number -10053 occurred
 Last message repeated 1 times
[out#0/mpegts @ 0000027081e684c0] Error muxing a packet
[out#0/mpegts @ 0000027081e684c0] Task finished with error code: -10053 (Error number -10053 occurred)
[out#0/mpegts @ 0000027081e684c0] Terminating thread with return code -10053 (Error number -10053 occurred)
[out#0/mpegts @ 0000027081e684c0] Error writing trailer: Error number -10053 occurred
[http @ 0000027081c47680] URL read error: Error number -10053 occurred
[out#0/mpegts @ 0000027081e684c0] Error closing file: Error number -10053 occurred
[out#0/mpegts @ 0000027081e684c0] video:0KiB audio:46KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 13.917515%
size= 52KiB time=00:00:02.94 bitrate= 145.1kbits/s speed= 1.2x
Conversion failed!



What is the correct way to stream this one locally in order to be listened in my internet radio ?
Shall I use ffmpeg or can be done directly with ngnix ? Or shall I use both ?


-
Video is not compressed with ffmpeg
16 octobre 2024, par Pooria DarvishiI wrote a wrapper for JNI in cpp language to compress the video :


#include <iostream>
#include <android></android>log.h>
#include 

extern "C" {
#include <libavcodec></libavcodec>avcodec.h>
#include <libavformat></libavformat>avformat.h>
#include <libavutil></libavutil>opt.h>
#include <libavutil></libavutil>log.h>
#include <libavutil></libavutil>time.h>
#include <libswscale></libswscale>swscale.h>
}

using namespace std;

#define LOG_TAG "VideoNative"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)


#define FFMPEG_LOG_TAG "FFMPEG_VideoNative"
#define FLOGD(...) __android_log_print(ANDROID_LOG_DEBUG, FFMPEG_LOG_TAG, __VA_ARGS__)
#define FLOGI(...) __android_log_print(ANDROID_LOG_INFO, FFMPEG_LOG_TAG, __VA_ARGS__)
#define FLOGE(...) __android_log_print(ANDROID_LOG_ERROR, FFMPEG_LOG_TAG, __VA_ARGS__)


AVFormatContext *initInputFormatContext(const char *path);

AVFormatContext *initOutputFormatContext(const char *path);

void copyAvFormatContext(AVFormatContext **inputContext, AVFormatContext **outputContext);


void writeFileHeader(AVFormatContext *formatContext);

static void ffmpeg_log_callback(void *ptr, int level, const char *fmt, va_list vargs) {
 if (level <= av_log_get_level()) {
 char log_buffer[1024];
 vsnprintf(log_buffer, sizeof(log_buffer), fmt, vargs);

 switch (level) {
 case AV_LOG_DEBUG:
 FLOGD("%s", log_buffer);
 break;
 case AV_LOG_WARNING:
 case AV_LOG_ERROR:
 case AV_LOG_FATAL:
 FLOGE("%s", log_buffer);
 break;
 default:
 FLOGI("%s", log_buffer);
 break;
 }
 }
}


void compress(const char *inputPath, const char *outputPath) {
 av_register_all();
 avcodec_register_all();
 avformat_network_init();
 av_log_set_level(AV_LOG_TRACE);
 av_log_set_callback(ffmpeg_log_callback);

 AVFormatContext *inputFormatContext = initInputFormatContext(inputPath);
 if (!inputFormatContext) {
 LOGE("input format context fail");
 return;
 }
 AVFormatContext *outputFormatContext = initOutputFormatContext(outputPath);
 if (!outputFormatContext) {
 LOGE("output format context fail");
 return;
 }

 copyAvFormatContext(&inputFormatContext, &outputFormatContext);

 if (avio_open2(&outputFormatContext->pb, outputPath, AVIO_FLAG_WRITE, nullptr, nullptr) < 0) {
 LOGE("error to open file");
 }

 writeFileHeader(outputFormatContext);

 AVPacket *inputPaket = av_packet_alloc();
 if (!inputPaket) {
 LOGE("packet not find");
 }
 while (av_read_frame(inputFormatContext, inputPaket) >= 0) {
 if (av_interleaved_write_frame(outputFormatContext, inputPaket) < 0) {
 LOGE("can not write frame");
 }
 }

 if (av_write_trailer(outputFormatContext) < 0) {
 LOGE("can not write trailer");
 }
}

void writeFileHeader(AVFormatContext *formatContext) {
 AVDictionary *option = nullptr;
 if (avformat_write_header(formatContext, &option) < 0) {
 LOGE("write header fail");
 return;
 }
 av_dict_free(&option);
}


void copyAvFormatContext(AVFormatContext **inputContext, AVFormatContext **outputContext) {
 int numStream = static_cast<int>((*inputContext)->nb_streams);
 for (int i = 0; i < numStream; i++) {
 AVStream *inputStream = (*inputContext)->streams[i];
 AVCodecParameters *inputCodecParams = inputStream->codecpar;
 AVCodec *outputCodec = avcodec_find_encoder(inputCodecParams->codec_id);
 AVStream *outputStream = avformat_new_stream(*outputContext, outputCodec);
 AVCodecContext *codecContext = avcodec_alloc_context3(outputCodec);
 codecContext->codec_id = AV_CODEC_ID_H264;
 av_opt_set(codecContext->priv_data, "crf", "30", 0);
 av_opt_set(codecContext->priv_data, "movflags", "faststart", 0);

 if (avcodec_parameters_from_context(outputStream->codecpar, codecContext) < 0) {
 LOGE("cant set option" );
 }
 AVCodecParameters *outputCodecParams = outputStream->codecpar;
 avcodec_parameters_copy(outputCodecParams, inputCodecParams);
 }
}

AVFormatContext *initOutputFormatContext(const char *path) {
 AVFormatContext *formatContext = avformat_alloc_context();

 if (avformat_alloc_output_context2(&formatContext, nullptr, "mp4", path) < 0) {
 LOGE("open output fail");
 return nullptr;
 }
 return formatContext;
}


AVFormatContext *initInputFormatContext(const char *path) {
 AVFormatContext *formatContext = avformat_alloc_context();
 if (avformat_open_input(&formatContext, path, nullptr, nullptr) != 0) {
 LOGE("open input fail");
 return nullptr;
 }
 if (avformat_find_stream_info(formatContext, nullptr) < 0) {
 LOGE("stream fail");
 return nullptr;
 }
 return formatContext;
}

extern "C"
JNIEXPORT jint JNICALL
Java_ir_nasim_core_modules_file_FileNativeLoader_compressFile(JNIEnv *env, jobject thiz,
 jstring input_path,
 jstring output_path) {
 compress(env->GetStringUTFChars(input_path, JNI_FALSE),
 env->GetStringUTFChars(output_path, JNI_FALSE));
 return 0;
}
</int></iostream>


...but the compression did not happen and the output video is exactly the same as the input video.