
Recherche avancée
Médias (1)
-
SWFUpload Process
6 septembre 2011, par
Mis à jour : Septembre 2011
Langue : français
Type : Texte
Autres articles (63)
-
Ecrire une actualité
21 juin 2013, parPré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 ) (...) -
Publier sur MédiaSpip
13 juin 2013Puis-je poster des contenus à partir d’une tablette Ipad ?
Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir -
Personnaliser en ajoutant son logo, sa bannière ou son image de fond
5 septembre 2013, parCertains 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 ;
Sur d’autres sites (13669)
-
Sending raw h264 video and aac audio frames to an RTMP server using ffmpeg
15 août 2016, par codeimpalerI am receiving raw h264 and aac audio frames from an even driven source. I am trying to send these frames to an rtmp server.
I started working from the ffmpeg example muxing.c which successfully sends a custom stream to the rtmp server. I figure I just need to replace their frame data with my own.I found this suggestion online. I have tried How to pack raw h264 stream to flv container and send over rtmp using ffmpeg (not command)
and
How to publish selfmade stream with ffmpeg and c++ to rtmp server ?
and a few other suggestions but none have worked for me.
I have tried to directly memcpy my byte buffer but my code keeps failing
at ret = avcodec_encode_video2(c, &pkt, frame, &got_packet).
Specifically, I get an invalid access error.
For a little more context, anytime I receive a frame (which is event driven), void RTMPWriter::WriteVideoFrame(...) is called. Assume the constructor has already been called before the first frame is received.
I am not that familiar with ffmpeg and there could be several things wrong with the code. Any input will be really appreciated.#define STREAM_FRAME_RATE 25 /* 25 images/s */
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
#define SCALE_FLAGS SWS_BICUBIC
RTMPWriter::RTMPWriter()
: seenKeyFrame(false),
video_st({ 0 }),
audio_st({ 0 }),
have_video(0),
have_audio(0)
{
const char *filename;
AVCodec *audio_codec = NULL, *video_codec = NULL;
int ret;
int encode_video = 0, encode_audio = 0;
AVDictionary *opt = NULL;
int i;
/* Initialize libavcodec, and register all codecs and formats. */
av_register_all();
avformat_network_init();
String^ StreamURL = "StreamURL";
String^ out_uri = safe_cast(ApplicationData::Current->LocalSettings->Values->Lookup(StreamURL));
std::wstring out_uriW(out_uri->Begin());
std::string out_uriA(out_uriW.begin(), out_uriW.end());
filename = out_uriA.c_str();
/* allocate the output media context */
avformat_alloc_output_context2(&oc, NULL, "flv", filename);
if (!oc)
{
OutputDebugString(L"Could not deduce output format from file extension: using MPEG.\n");
avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
}
if (!oc)
{
OutputDebugString(L"Could not allocate using MPEG.\n");
}
fmt = oc->oformat;
/* Add the audio and video streams using the default format codecs
* and initialize the codecs. */
if (fmt->video_codec != AV_CODEC_ID_NONE) {
add_stream(&video_st, oc, &video_codec, fmt->video_codec);
have_video = 1;
encode_video = 1;
}
if (fmt->audio_codec != AV_CODEC_ID_NONE) {
add_stream(&audio_st, oc, &audio_codec, fmt->audio_codec);
have_audio = 1;
encode_audio = 1;
}
/* Now that all the parameters are set, we can open the audio and
* video codecs and allocate the necessary encode buffers. */
if (have_video)
{
open_video(oc, video_codec, &video_st, opt);
}
if (have_audio)
{
open_audio(oc, audio_codec, &audio_st, opt);
}
av_dump_format(oc, 0, filename, 1);
/* open the output file, if needed */
if (!(fmt->flags & AVFMT_NOFILE))
{
ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
if (ret < 0)
{
OutputDebugString(L"Could not open ");
OutputDebugString(out_uri->Data());
}
}
/* Write the stream header, if any. */
ret = avformat_write_header(oc, &opt);
if (ret < 0)
{
OutputDebugString(L"Error occurred when writing stream header \n");
}
}
void RTMPWriter::WriteVideoFrame(
boolean isKeyFrame,
boolean hasDiscontinuity,
UINT64 frameId,
UINT32 videoBufferLength,
BYTE *videoBytes)
{
int ret;
AVCodecContext *c;
AVFrame* frame;
int got_packet = 0;
AVPacket pkt = { 0 };
c = video_st.enc;
frame = get_video_frame(videoBufferLength, videoBytes);
/* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
if (ret < 0) {
OutputDebugString(L"Error encoding video frame: \n")
}
if (got_packet)
{
ret = write_frame(oc, &c->time_base, video_st.st, &pkt);
}
else {
ret = 0;
}
if (ret < 0) {
OutputDebugString(L"Error while writing video frame: %s\n");
}
}
AVFrame * RTMPWriter::get_video_frame(
UINT32 videoBufferLength,
BYTE *videoBytes)
{
AVCodecContext *c = video_st.enc;
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
/* as we only generate a YUV420P picture, we must convert it
* to the codec pixel format if needed */
if (!video_st.sws_ctx) {
video_st.sws_ctx = sws_getContext(c->width, c->height,
AV_PIX_FMT_YUV420P,
c->width, c->height,
c->pix_fmt,
SCALE_FLAGS, NULL, NULL, NULL);
if (!video_st.sws_ctx) {
fprintf(stderr,
"Could not initialize the conversion context\n");
exit(1);
}
}
fill_yuv_image(video_st.tmp_frame, video_st.next_pts, c->width, c->height, videoBufferLength, videoBytes);
sws_scale(video_st.sws_ctx,
(const uint8_t * const *)video_st.tmp_frame->data, video_st.tmp_frame->linesize,
0, c->height, video_st.frame->data, video_st.frame->linesize);
}
else {
fill_yuv_image(video_st.frame, video_st.next_pts, c->width, c->height, videoBufferLength, videoBytes);
}
video_st.frame->pts = video_st.next_pts++;
return video_st.frame;
}
/* Prepare a dummy image. */
void RTMPWriter::fill_yuv_image(
AVFrame *pict,
int frame_index,
int width,
int height,
UINT32 videoBufferLength,
BYTE *videoBytes)
{
//int x, y, i, ret;
/* when we pass a frame to the encoder, it may keep a reference to it
* internally;
* make sure we do not overwrite it here
*/
ret = av_frame_make_writable(pict);
if (ret < 0)
{
OutputDebugString(L"Unable to make piture writable");
}
memcpy(pict->data, videoBytes, videoBufferLength);
//i = frame_index;
///* Y */
//for (y = 0; y < height; y++)
// for (x = 0; x < width; x++)
// pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
///* Cb and Cr */
//for (y = 0; y < height / 2; y++) {
// for (x = 0; x < width / 2; x++) {
// pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
// pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
// }
//}
}
void RTMPWriter::WriteAudioFrame()
{
}
/* Add an output stream. */
void RTMPWriter::add_stream(
OutputStream *ost,
AVFormatContext *oc,
AVCodec **codec,
enum AVCodecID codec_id)
{
AVCodecContext *c;
int i;
/* find the encoder */
*codec = avcodec_find_encoder(codec_id);
if (!(*codec)) {
OutputDebugString(L"Could not find encoder for '%s'\n");
//avcodec_get_name(codec_id));
exit(1);
}
ost->st = avformat_new_stream(oc, NULL);
if (!ost->st) {
OutputDebugString(L"Could not allocate stream\n");
exit(1);
}
ost->st->id = oc->nb_streams - 1;
c = avcodec_alloc_context3(*codec);
if (!c) {
OutputDebugString(L"Could not alloc an encoding context\n");
exit(1);
}
ost->enc = c;
switch ((*codec)->type) {
case AVMEDIA_TYPE_AUDIO:
c->sample_fmt = (*codec)->sample_fmts ?
(*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
c->bit_rate = 64000;
c->sample_rate = 44100;
if ((*codec)->supported_samplerates) {
c->sample_rate = (*codec)->supported_samplerates[0];
for (i = 0; (*codec)->supported_samplerates[i]; i++) {
if ((*codec)->supported_samplerates[i] == 44100)
c->sample_rate = 44100;
}
}
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
c->channel_layout = AV_CH_LAYOUT_STEREO;
if ((*codec)->channel_layouts) {
c->channel_layout = (*codec)->channel_layouts[0];
for (i = 0; (*codec)->channel_layouts[i]; i++) {
if ((*codec)->channel_layouts[i] == AV_CH_LAYOUT_STEREO)
c->channel_layout = AV_CH_LAYOUT_STEREO;
}
}
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
ost->st->time_base = /*(AVRational)*/{ 1, c->sample_rate };
break;
case AVMEDIA_TYPE_VIDEO:
c->codec_id = codec_id;
c->bit_rate = 400000;
/* Resolution must be a multiple of two. */
c->width = 352;
c->height = 288;
/* timebase: This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented. For fixed-fps content,
* timebase should be 1/framerate and timestamp increments should be
* identical to 1. */
ost->st->time_base = /*(AVRational)*/{ 1, STREAM_FRAME_RATE };
c->time_base = ost->st->time_base;
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
c->pix_fmt = STREAM_PIX_FMT;
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
/* just for testing, we also add B-frames */
c->max_b_frames = 2;
}
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
/* Needed to avoid using macroblocks in which some coeffs overflow.
* This does not happen with normal video, it just happens here as
* the motion of the chroma plane does not match the luma plane. */
c->mb_decision = 2;
}
break;
default:
break;
}
/* Some formats want stream headers to be separate. */
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}
AVFrame * RTMPWriter::alloc_audio_frame(
enum AVSampleFormat sample_fmt,
uint64_t channel_layout,
int sample_rate, int nb_samples)
{
AVFrame *frame = av_frame_alloc();
int ret;
if (!frame) {
OutputDebugString(L"Error allocating an audio frame\n");
exit(1);
}
frame->format = sample_fmt;
frame->channel_layout = channel_layout;
frame->sample_rate = sample_rate;
frame->nb_samples = nb_samples;
if (nb_samples) {
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
OutputDebugString(L"Error allocating an audio buffer\n");
exit(1);
}
}
return frame;
}
void RTMPWriter::open_audio(
AVFormatContext *oc,
AVCodec *codec,
OutputStream *ost,
AVDictionary *opt_arg)
{
AVCodecContext *c;
int nb_samples;
int ret;
AVDictionary *opt = NULL;
c = ost->enc;
/* open it */
av_dict_copy(&opt, opt_arg, 0);
ret = avcodec_open2(c, codec, &opt);
av_dict_free(&opt);
if (ret < 0) {
OutputDebugString(L"Could not open audio codec: %s\n");// , av_err2str(ret));
exit(1);
}
/* init signal generator */
ost->t = 0;
ost->tincr = 2 * M_PI * 110.0 / c->sample_rate;
/* increment frequency by 110 Hz per second */
ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
nb_samples = 10000;
else
nb_samples = c->frame_size;
ost->frame = alloc_audio_frame(c->sample_fmt, c->channel_layout,
c->sample_rate, nb_samples);
ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
c->sample_rate, nb_samples);
/* copy the stream parameters to the muxer */
ret = avcodec_parameters_from_context(ost->st->codecpar, c);
if (ret < 0) {
OutputDebugString(L"Could not copy the stream parameters\n");
exit(1);
}
/* create resampler context */
ost->swr_ctx = swr_alloc();
if (!ost->swr_ctx) {
OutputDebugString(L"Could not allocate resampler context\n");
exit(1);
}
/* set options */
av_opt_set_int(ost->swr_ctx, "in_channel_count", c->channels, 0);
av_opt_set_int(ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
av_opt_set_int(ost->swr_ctx, "out_channel_count", c->channels, 0);
av_opt_set_int(ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
/* initialize the resampling context */
if ((ret = swr_init(ost->swr_ctx)) < 0) {
OutputDebugString(L"Failed to initialize the resampling context\n");
exit(1);
}
}
int RTMPWriter::write_frame(
AVFormatContext *fmt_ctx,
const AVRational *time_base,
AVStream *st,
AVPacket *pkt)
{
/* rescale output packet timestamp values from codec to stream timebase */
av_packet_rescale_ts(pkt, *time_base, st->time_base);
pkt->stream_index = st->index;
/* Write the compressed frame to the media file. */
//log_packet(fmt_ctx, pkt);
OutputDebugString(L"Actually sending video frame: %s\n");
return av_interleaved_write_frame(fmt_ctx, pkt);
}
AVFrame *RTMPWriter::alloc_picture(
enum AVPixelFormat pix_fmt,
int width,
int height)
{
AVFrame *picture;
int ret;
picture = av_frame_alloc();
if (!picture)
return NULL;
picture->format = pix_fmt;
picture->width = width;
picture->height = height;
/* allocate the buffers for the frame data */
ret = av_frame_get_buffer(picture, 32);
if (ret < 0) {
fprintf(stderr, "Could not allocate frame data.\n");
exit(1);
}
return picture;
}
void RTMPWriter::open_video(
AVFormatContext *oc,
AVCodec *codec,
OutputStream *ost,
AVDictionary *opt_arg)
{
int ret;
AVCodecContext *c = ost->enc;
AVDictionary *opt = NULL;
av_dict_copy(&opt, opt_arg, 0);
/* open the codec */
ret = avcodec_open2(c, codec, &opt);
av_dict_free(&opt);
if (ret < 0) {
OutputDebugString(L"Could not open video codec: %s\n");// , av_err2str(ret));
exit(1);
}
/* allocate and init a re-usable frame */
ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
if (!ost->frame) {
OutputDebugString(L"Could not allocate video frame\n");
exit(1);
}
/* If the output format is not YUV420P, then a temporary YUV420P
* picture is needed too. It is then converted to the required
* output format. */
ost->tmp_frame = NULL;
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
if (!ost->tmp_frame) {
OutputDebugString(L"Could not allocate temporary picture\n");
exit(1);
}
}
/* copy the stream parameters to the muxer */
ret = avcodec_parameters_from_context(ost->st->codecpar, c);
if (ret < 0) {
OutputDebugString(L"Could not copy the stream parameters\n");
exit(1);
}
}
void RTMPWriter::close_stream(AVFormatContext *oc, OutputStream *ost)
{
avcodec_free_context(&ost->enc);
av_frame_free(&ost->frame);
av_frame_free(&ost->tmp_frame);
sws_freeContext(ost->sws_ctx);
swr_free(&ost->swr_ctx);
}
RTMPWriter::~RTMPWriter()
{
av_write_trailer(oc);
/* Close each codec. */
if (have_video)
close_stream(oc, &video_st);
if (have_audio)
close_stream(oc, &audio_st);
if (!(fmt->flags & AVFMT_NOFILE))
/* Close the output file. */
avio_closep(&oc->pb);
/* free the stream */
avformat_free_context(oc);
} -
Révision 99151 : Fix https://core.spip.net/issues/3520 : déplier les blocs des referers uniquement...
13 août 2016, par brunobergot@gmail.comOpera est un peu concon car il déclenche l’event onclick si on utilise le clic milieu
-
Pygame : Frame ghosting ?
31 décembre 2013, par Sam TubbI am working on a animation environment in python using pygame. The user draw's each frame, and then using ffmpeg the animation is saved as an .avi movie. I would like to implement a feature, but am not sure how.. frame ghosting. Like display the previous frame while you draw the current.
I tried creating a surface called
ghost
that copies the current frame when the next-frame key is pressed. Then draws it with an alpha level of 10, but this didn't work out correctly.I am not sure what to do, here is the source code for anyone that thinks they have an idea :
#Anim8
import pygame,subprocess,shutil
from os import makedirs
from pygame.locals import *
from random import randrange
pygame.init()
screen=pygame.display.set_mode((740,580))
draw=pygame.Surface((740,540))
draw.fill((200,200,200))
bcol=(200,200,200)
gui=pygame.Surface((740,40))
gui.fill((50,50,50))
size=2
color=(0,0,0)
screen.fill((200,200,200))
prevcol=0
newcol=0
f=0
msg=''
framerate=60
try:
makedirs('anim')
except:
pass
def DrawColors(x,y):
pygame.draw.rect(gui, (255,0,0), (x+3,y+3,15,15),0)
pygame.draw.rect(gui, (0,0,0), (x+3,y+21,15,15),0)
pygame.draw.rect(gui, (0,255,0), (x+21,y+3,15,15),0)
pygame.draw.rect(gui, (200,200,200), (x+21,y+21,15,15),0)
pygame.draw.rect(gui, (0,0,255), (x+39,y+3,15,15),0)
while True:
pygame.display.set_caption('Anim8 - Sam Tubb - '+'Frame: '+str(f)+' '+str(msg))
mse=pygame.mouse.get_pos()
screen.blit(gui, (0,0))
DrawColors(0,0)
screen.blit(draw,(0,40))
key=pygame.key.get_pressed()
if key[K_1]:
framerate=10
msg='Frame Rate set to 10'
if key[K_2]:
framerate=20
msg='Frame Rate set to 20'
if key[K_3]:
framerate=30
msg='Frame Rate set to 30'
if key[K_4]:
framerate=40
msg='Frame Rate set to 40'
if key[K_5]:
framerate=50
msg='Frame Rate set to 50'
if key[K_6]:
framerate=60
msg='Frame Rate set to 60'
if key[K_7]:
framerate=70
msg='Frame Rate set to 70'
if key[K_8]:
framerate=80
msg='Frame Rate set to 80'
if key[K_9]:
framerate=90
msg='Frame Rate set to 90'
if key[K_0]:
framerate=100
msg='Frame Rate set to 100'
if key[K_a]:
pygame.image.save(draw, 'anim/frame'+str(f)+'.png')
f+=1
for e in pygame.event.get():
if e.type==QUIT:
shutil.rmtree('anim')
exit()
if e.type==KEYDOWN:
if e.key==K_s:
msg='Added Frame!'
pygame.image.save(draw, 'anim/frame'+str(f)+'.png')
f+=1
if e.key==K_c:
draw.fill(bcol)
if e.key==K_r:
name='anim'+str(randrange(0,999))+str(randrange(0,999))+'.avi'
msg='Rendering: '+name
pygame.display.set_caption('Anim8 - Sam Tubb - '+'Frame: '+str(f)+' '+str(msg))
subprocess.call('ffmpeg -f image2 -s 640x480 -i anim/frame%01d.png -r '+str(framerate)+' '+name,shell=True)
msg='Done!'
if e.key==K_p:
subprocess.call('ffplay '+name,shell=True)
if e.type==MOUSEBUTTONDOWN:
if e.button==1:
try:
prevcol=color
newcol=gui.get_at(mse)
if newcol==(50,50,50):
newcol=prevcol
color=newcol
except:
pass
if e.button==3:
try:
prevcol=bcol
newcol=gui.get_at(mse)
if newcol==(50,50,50):
newcol=prevcol
draw.fill(newcol)
bcol=newcol
except:
pass
if e.button==4:
size+=1
if size>7:
size=7
if e.button==5:
size-=1
if size==0:
size=1
if e.type == pygame.MOUSEMOTION:
lineEnd = pygame.mouse.get_pos()
lineEnd = (lineEnd[0],lineEnd[1]-40)
if pygame.mouse.get_pressed() == (1, 0, 0):
pygame.draw.line(draw, color, lineStart, lineEnd, size)
lineStart = lineEnd
pygame.display.flip()Oh, and on another note, just if anyone was curious, here is what the output looks like.. I made a little new year's animation :