
Recherche avancée
Médias (1)
-
Rennes Emotion Map 2010-11
19 octobre 2011, par
Mis à jour : Juillet 2013
Langue : français
Type : Texte
Autres articles (88)
-
Organiser par catégorie
17 mai 2013, parDans MédiaSPIP, une rubrique a 2 noms : catégorie et rubrique.
Les différents documents stockés dans MédiaSPIP peuvent être rangés dans différentes catégories. On peut créer une catégorie en cliquant sur "publier une catégorie" dans le menu publier en haut à droite ( après authentification ). Une catégorie peut être rangée dans une autre catégorie aussi ce qui fait qu’on peut construire une arborescence de catégories.
Lors de la publication prochaine d’un document, la nouvelle catégorie créée sera proposée (...) -
Récupération d’informations sur le site maître à l’installation d’une instance
26 novembre 2010, parUtilité
Sur le site principal, une instance de mutualisation est définie par plusieurs choses : Les données dans la table spip_mutus ; Son logo ; Son auteur principal (id_admin dans la table spip_mutus correspondant à un id_auteur de la table spip_auteurs)qui sera le seul à pouvoir créer définitivement l’instance de mutualisation ;
Il peut donc être tout à fait judicieux de vouloir récupérer certaines de ces informations afin de compléter l’installation d’une instance pour, par exemple : récupérer le (...) -
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
Sur d’autres sites (6690)
-
encode h264 video using ffmpeg library memory issues
31 mars 2015, par ZeppaI’m trying to do screen capture on OS X using ffmpeg’s
avfoundation
library. I capture frames from the screen and encode it using H264 into an flv container.Here’s the command line output of the program :
Input #0, avfoundation, from 'Capture screen 0':
Duration: N/A, start: 9.253649, bitrate: N/A
Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 1440x900, 14.58 tbr, 1000k tbn, 1000k tbc
raw video is inCodec
FLV (Flash Video)http://localhost:8090/test.flv
[libx264 @ 0x102038e00] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 @ 0x102038e00] profile High, level 4.0
[libx264 @ 0x102038e00] 264 - core 142 r2495 6a301b6 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=1 weightp=2 keyint=50 keyint_min=5 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=abr mbtree=1 bitrate=400 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
[tcp @ 0x101a5fe70] Connection to tcp://localhost:8090 failed (Connection refused), trying next address
[tcp @ 0x101a5fe70] Connection to tcp://localhost:8090 failed: Connection refused
url_fopen failed: Operation now in progress
[flv @ 0x102038800] Using AVStream.codec.time_base as a timebase hint to the muxer is deprecated. Set AVStream.time_base instead.
encoded frame #0
encoded frame #1
......
encoded frame #49
encoded frame #50
testmee(8404,0x7fff7e05c300) malloc: *** error for object 0x102053e08: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
(lldb) bt
* thread #10: tid = 0x43873, 0x00007fff95639286 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT
* frame #0: 0x00007fff95639286 libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x00007fff9623742f libsystem_pthread.dylib`pthread_kill + 90
frame #2: 0x00007fff977ceb53 libsystem_c.dylib`abort + 129
frame #3: 0x00007fff9ab59e06 libsystem_malloc.dylib`szone_error + 625
frame #4: 0x00007fff9ab4f799 libsystem_malloc.dylib`small_malloc_from_free_list + 1105
frame #5: 0x00007fff9ab4d3bc libsystem_malloc.dylib`szone_malloc_should_clear + 1449
frame #6: 0x00007fff9ab4c877 libsystem_malloc.dylib`malloc_zone_malloc + 71
frame #7: 0x00007fff9ab4b395 libsystem_malloc.dylib`malloc + 42
frame #8: 0x00007fff94aa63d2 IOSurface`IOSurfaceClientLookupFromMachPort + 40
frame #9: 0x00007fff94aa6b38 IOSurface`IOSurfaceLookupFromMachPort + 12
frame #10: 0x00007fff92bfa6b2 CoreGraphics`_CGYDisplayStreamFrameAvailable + 342
frame #11: 0x00007fff92f6759c CoreGraphics`CGYDisplayStreamNotification_server + 336
frame #12: 0x00007fff92bfada6 CoreGraphics`display_stream_runloop_callout + 46
frame #13: 0x00007fff956eba07 CoreFoundation`__CFMachPortPerform + 247
frame #14: 0x00007fff956eb8f9 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
frame #15: 0x00007fff956eb86b CoreFoundation`__CFRunLoopDoSource1 + 475
frame #16: 0x00007fff956dd3e7 CoreFoundation`__CFRunLoopRun + 2375
frame #17: 0x00007fff956dc858 CoreFoundation`CFRunLoopRunSpecific + 296
frame #18: 0x00007fff95792ef1 CoreFoundation`CFRunLoopRun + 97
frame #19: 0x0000000105f79ff1 CMIOUnits`___lldb_unnamed_function2148$$CMIOUnits + 875
frame #20: 0x0000000105f6f2c2 CMIOUnits`___lldb_unnamed_function2127$$CMIOUnits + 14
frame #21: 0x00007fff97051765 CoreMedia`figThreadMain + 417
frame #22: 0x00007fff96235268 libsystem_pthread.dylib`_pthread_body + 131
frame #23: 0x00007fff962351e5 libsystem_pthread.dylib`_pthread_start + 176
frame #24: 0x00007fff9623341d libsystem_pthread.dylib`thread_start + 13I’ve attached the code I used below.
#include <libavcodec></libavcodec>avcodec.h>
#include <libavformat></libavformat>avformat.h>
#include <libswscale></libswscale>swscale.h>
#include <libavdevice></libavdevice>avdevice.h>
#include <libavutil></libavutil>opt.h>
#include
#include
#include
/* compile using
gcc -g -o stream test.c -lavformat -lavutil -lavcodec -lavdevice -lswscale
*/
// void show_av_device() {
// inFmt->get_device_list(inFmtCtx, device_list);
// printf("Device Info=============\n");
// //avformat_open_input(&inFmtCtx,"video=Capture screen 0",inFmt,&inOptions);
// printf("===============================\n");
// }
void AVFAIL (int code, const char *what) {
char msg[500];
av_strerror(code, msg, sizeof(msg));
fprintf(stderr, "failed: %s\nerror: %s\n", what, msg);
exit(2);
}
#define AVCHECK(f) do { int e = (f); if (e < 0) AVFAIL(e, #f); } while (0)
#define AVCHECKPTR(p,f) do { p = (f); if (!p) AVFAIL(AVERROR_UNKNOWN, #f); } while (0)
void registerLibs() {
av_register_all();
avdevice_register_all();
avformat_network_init();
avcodec_register_all();
}
int main(int argc, char *argv[]) {
//conversion variables
struct SwsContext *swsCtx = NULL;
//input stream variables
AVFormatContext *inFmtCtx = NULL;
AVCodecContext *inCodecCtx = NULL;
AVCodec *inCodec = NULL;
AVInputFormat *inFmt = NULL;
AVFrame *inFrame = NULL;
AVDictionary *inOptions = NULL;
const char *streamURL = "http://localhost:8090/test.flv";
const char *name = "avfoundation";
// AVFrame *inFrameYUV = NULL;
AVPacket inPacket;
//output stream variables
AVCodecContext *outCodecCtx = NULL;
AVCodec *outCodec;
AVFormatContext *outFmtCtx = NULL;
AVOutputFormat *outFmt = NULL;
AVFrame *outFrameYUV = NULL;
AVStream *stream = NULL;
int i, videostream, ret;
int numBytes, frameFinished;
registerLibs();
inFmtCtx = avformat_alloc_context(); //alloc input context
av_dict_set(&inOptions, "pixel_format", "uyvy422", 0);
av_dict_set(&inOptions, "probesize", "7000000", 0);
inFmt = av_find_input_format(name);
ret = avformat_open_input(&inFmtCtx, "Capture screen 0:", inFmt, &inOptions);
if (ret < 0) {
printf("Could not load the context for the input device\n");
return -1;
}
if (avformat_find_stream_info(inFmtCtx, NULL) < 0) {
printf("Could not find stream info for screen\n");
return -1;
}
av_dump_format(inFmtCtx, 0, "Capture screen 0", 0);
// inFmtCtx->streams is an array of pointers of size inFmtCtx->nb_stream
videostream = av_find_best_stream(inFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &inCodec, 0);
if (videostream == -1) {
printf("no video stream found\n");
return -1;
} else {
printf("%s is inCodec\n", inCodec->long_name);
}
inCodecCtx = inFmtCtx->streams[videostream]->codec;
// open codec
if (avcodec_open2(inCodecCtx, inCodec, NULL) > 0) {
printf("Couldn't open codec");
return -1; // couldn't open codec
}
//setup output params
outFmt = av_guess_format(NULL, streamURL, NULL);
if(outFmt == NULL) {
printf("output format was not guessed properly");
return -1;
}
if((outFmtCtx = avformat_alloc_context()) < 0) {
printf("output context not allocated. ERROR");
return -1;
}
printf("%s", outFmt->long_name);
outFmtCtx->oformat = outFmt;
snprintf(outFmtCtx->filename, sizeof(outFmtCtx->filename), streamURL);
printf("%s\n", outFmtCtx->filename);
outCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
if(!outCodec) {
printf("could not find encoder for H264 \n" );
return -1;
}
stream = avformat_new_stream(outFmtCtx, outCodec);
outCodecCtx = stream->codec;
avcodec_get_context_defaults3(outCodecCtx, outCodec);
outCodecCtx->codec_id = AV_CODEC_ID_H264;
outCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
outCodecCtx->flags = CODEC_FLAG_GLOBAL_HEADER;
outCodecCtx->width = inCodecCtx->width;
outCodecCtx->height = inCodecCtx->height;
outCodecCtx->time_base.den = 25;
outCodecCtx->time_base.num = 1;
outCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
outCodecCtx->gop_size = 50;
outCodecCtx->bit_rate = 400000;
//setup output encoders etc
if(stream) {
ret = avcodec_open2(outCodecCtx, outCodec, NULL);
if (ret < 0) {
printf("Could not open output encoder");
return -1;
}
}
if (avio_open(&outFmtCtx->pb, outFmtCtx->filename, AVIO_FLAG_WRITE ) < 0) {
perror("url_fopen failed");
}
avio_open_dyn_buf(&outFmtCtx->pb);
ret = avformat_write_header(outFmtCtx, NULL);
if (ret != 0) {
printf("was not able to write header to output format");
return -1;
}
unsigned char *pb_buffer;
int len = avio_close_dyn_buf(outFmtCtx->pb, (unsigned char **)(&pb_buffer));
avio_write(outFmtCtx->pb, (unsigned char *)pb_buffer, len);
numBytes = avpicture_get_size(PIX_FMT_UYVY422, inCodecCtx->width, inCodecCtx->height);
// Allocate video frame
inFrame = av_frame_alloc();
swsCtx = sws_getContext(inCodecCtx->width, inCodecCtx->height, inCodecCtx->pix_fmt, inCodecCtx->width,
inCodecCtx->height, PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);
int frame_count = 0;
while(av_read_frame(inFmtCtx, &inPacket) >= 0) {
if(inPacket.stream_index == videostream) {
avcodec_decode_video2(inCodecCtx, inFrame, &frameFinished, &inPacket);
// 1 Frame might need more than 1 packet to be filled
if(frameFinished) {
outFrameYUV = av_frame_alloc();
uint8_t *buffer = (uint8_t *)av_malloc(numBytes);
int ret = avpicture_fill((AVPicture *)outFrameYUV, buffer, PIX_FMT_YUV420P,
inCodecCtx->width, inCodecCtx->height);
if(ret < 0){
printf("%d is return val for fill\n", ret);
return -1;
}
//convert image to YUV
sws_scale(swsCtx, (uint8_t const * const* )inFrame->data,
inFrame->linesize, 0, inCodecCtx->height,
outFrameYUV->data, outFrameYUV->linesize);
//outFrameYUV now holds the YUV scaled frame/picture
outFrameYUV->format = outCodecCtx->pix_fmt;
outFrameYUV->width = outCodecCtx->width;
outFrameYUV->height = outCodecCtx->height;
AVPacket pkt;
int got_output;
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
outFrameYUV->pts = frame_count;
ret = avcodec_encode_video2(outCodecCtx, &pkt, outFrameYUV, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
return -1;
}
if(got_output) {
if(stream->codec->coded_frame->key_frame) {
pkt.flags |= AV_PKT_FLAG_KEY;
}
pkt.stream_index = stream->index;
if(pkt.pts != AV_NOPTS_VALUE)
pkt.pts = av_rescale_q(pkt.pts, stream->codec->time_base, stream->time_base);
if(pkt.dts != AV_NOPTS_VALUE)
pkt.dts = av_rescale_q(pkt.dts, stream->codec->time_base, stream->time_base);
if(avio_open_dyn_buf(&outFmtCtx->pb)!= 0) {
printf("ERROR: Unable to open dynamic buffer\n");
}
ret = av_interleaved_write_frame(outFmtCtx, &pkt);
unsigned char *pb_buffer;
int len = avio_close_dyn_buf(outFmtCtx->pb, (unsigned char **)&pb_buffer);
avio_write(outFmtCtx->pb, (unsigned char *)pb_buffer, len);
} else {
ret = 0;
}
if(ret != 0) {
fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
exit(1);
}
fprintf(stderr, "encoded frame #%d\n", frame_count);
frame_count++;
av_free_packet(&pkt);
av_frame_free(&outFrameYUV);
av_free(buffer);
}
}
av_free_packet(&inPacket);
}
av_write_trailer(outFmtCtx);
//close video stream
if(stream) {
avcodec_close(outCodecCtx);
}
for (i = 0; i < outFmtCtx->nb_streams; i++) {
av_freep(&outFmtCtx->streams[i]->codec);
av_freep(&outFmtCtx->streams[i]);
}
if (!(outFmt->flags & AVFMT_NOFILE))
/* Close the output file. */
avio_close(outFmtCtx->pb);
/* free the output format context */
avformat_free_context(outFmtCtx);
// Free the YUV frame populated by the decoder
av_free(inFrame);
// Close the video codec (decoder)
avcodec_close(inCodecCtx);
// Close the input video file
avformat_close_input(&inFmtCtx);
return 1;
}I’m not sure what I’ve done wrong here. But, what I’ve observed is that for each frame thats been encoded, my memory usage goes up by about 6MB. Backtracking afterward usually leads one of the following two culprits :
- avf_read_frame function in avfoundation.m
- av_dup_packet function in avpacket.h
Can I also get advice on the way I’m using avio_open_dyn_buff function to be able to stream over http? I’ve also attached my ffmpeg library versions below :
ffmpeg version N-70876-g294bb6c Copyright (c) 2000-2015 the FFmpeg developers
built with Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
configuration: --prefix=/usr/local --enable-gpl --enable-postproc --enable-pthreads --enable-libmp3lame --enable-libtheora --enable-libx264 --enable-libvorbis --disable-mmx --disable-ssse3 --disable-armv5te --disable-armv6 --disable-neon --enable-shared --disable-static --disable-stripping
libavutil 54. 20.100 / 54. 20.100
libavcodec 56. 29.100 / 56. 29.100
libavformat 56. 26.101 / 56. 26.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 13.101 / 5. 13.101
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
Hyper fast Audio and Video encoderValgrind analysis attached here because I exceeded stack overflow’s character limit. http://pastebin.com/MPeRhjhN
-
Converted Avi to Mp4 using FFMPEG, Converted video not working in html 5 Tag
21 mars 2015, par SuprabhatI have a section in my web page where user can upload any types of videos of any format , currently only restricted to .mp4 and .avi. After successfull upload i have displayed the same video to the user. I have bind the path in HTML5 video so that the user can view the content he/she has uploded. Video with extension .mp4 no doubt are working properly as HTML5 support them. Tricky part is it don’t support Avi files. Now here what the problem has arised. In order to display avi videos i have used FFMPEG to convert videos with extension .avi to .mp4. With lots of googling and reading forum, i have succesfully converted avi videos to mp4 . Here’s what i have used :-
-
ffmpeg -i input.avi -acodec libfaac -b:a 128k -vcodec mpeg4 -b:v 1200k -flags +aic+mv4 output.mp4
-
ffmpeg -i input.avi -c:v libx264 -b:a 128k -vcodec mpeg4 -b:v 1200k -flags +aic+mv4 output.mp4
Above two are working perfectly, they have succesfully converted the video. But when i run them on browser in HTML5 and in new tab (Flash Player Plugin Installed), HTML5 doesn’t play it and flash player return an error message "Video can’t be played because the file is corrupt". But when i played them on KMplayer and in Window media player they are running perfectly.
I have been to various threads in stackoverflow related to convert avi to mp4 and here i found following in one of the forum. where one of user has accepted this a correct answer but it ain’t worked out for me.
ffmpeg -y -i sample.avi -b:v 1500k -vcodec libx264 -vpre slow -vpre baseline -g 30 sample.mp4
Above argument returned me following error "File for preset ’slow’ not found".
Following my futher searches i came across this thread ffmpeg convert mov file to mp4 for HTML5 video tag IE9. Here following argument worked perfectly and it able to convert video in such way that it is playble on browser.
ffmpeg -y -i input.avi -vcodec libx264 -vprofile high -preset slow -b:v 500k -maxrate 500k -bufsize 1000k -vf scale=-1:480 -threads 0 -acodec libvo_aacenc -b:a 128k -pix_fmt yuv420p output.mp4
.
Problem i faced here was video is converted to 420p reso which quality is noty upto mark. Smaller resolution videos are been enlarged and seems pixelated
Thus, i had to finally put up a question. I will be very obliged if someone can give a solution for above problem. I need to convert an avi video to mp4 supported by HTML5 video tag. It should able to play it on browser and during conversion of video it should maintain original audio and video quality plus resolution.
Thanks
My C# Code :
public void Create(string input, string output, string parametri, string ThumbnailPhysicalPath, int ConvertType)
{
ffmpeg = new Process();
if (ConvertType == Convert.ToInt32(ConversionType.Thumbnail))
ffmpeg.StartInfo.Arguments = " -i \"" + input + "\" -vframes 1 \"" + output + "\"";
else if (ConvertType == Convert.ToInt32(ConversionType.AviToMp4))
ffmpeg.StartInfo.Arguments = " -i \"" + input + "\" -c:v libx264 -b:a 128k -vcodec mpeg4 -b:v 1200k -flags +aic+mv4 \"" + output + "\"";
//ffmpeg.StartInfo.Arguments = " -i \"" + input + "\" -vcodec libx264 -vprofile high -preset slow -b:v 500k -maxrate 500k -bufsize 1000k -vf scale=-1:480 -threads 0 -acodec libvo_aacenc -b:a 128k -pix_fmt yuv420p \"" + output + "\"";
ffmpeg.StartInfo.FileName = ThumbnailPhysicalPath + @"ffmpeg.exe";
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.RedirectStandardOutput = true;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.StartInfo.CreateNoWindow = true;
try
{
ffmpeg.Start();
ffmpeg.WaitForExit();
string error = ffmpeg.StandardError.ReadToEnd();
}
catch (Exception Ex)
{
Common.WriteLog("Exception occurred during conversion. Error Message :- " + Ex.Message + "\n Input Parameter :- " + input+ "\n Output Paramenter :- "+ output);
}
finally
{
ffmpeg.Close();
if (ConvertType == Convert.ToInt32(ConversionType.AviToMp4))
UpdateConvertedVideoDetails(input,output);
}
}Command Prompt FFMPEG Output :-
Sample 3 Result :-
D:\Client\WebSite\Converter_Tools>ffmpeg -y -i sample.avi -b:v 1500k -vcodec libx264 -vpre slow -vpre baseline -g 30 sample.mp4
ffmpeg version N-70239-g111d79a Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 4.9.2 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrw
b --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --
enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enab
le-zlib
libavutil 54. 19.100 / 54. 19.100
libavcodec 56. 26.100 / 56. 26.100
libavformat 56. 23.105 / 56. 23.105
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 11.101 / 5. 11.101
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
[avi @ 037c8480] non-interleaved AVI
Guessed Channel Layout for Input Stream #0.1 : mono
Input #0, avi, from 'sample.avi':
Duration: 00:00:34.00, start: 0.000000, bitrate: 1433 kb/s
Stream #0:0: Video: cinepak (cvid / 0x64697663), rgb24, 320x240, 15 fps, 15 tbr, 15 tbn, 15 tbc
Stream #0:1: Audio: pcm_u8 ([1][0][0][0] / 0x0001), 22050 Hz, 1 channels, u8, 176 kb/s
File for preset 'slow' not foundSample 4 Result :-
D:\Client\WebSite\Converter_Tools>ffmpeg -y -i input.avi -vcodec libx264 -vprofile high -preset slow -b:v 500k -maxrate 500k -bufsize 1000k -vf scale=-1:480 -threads 0 -acodec libvo_
aacenc -b:a 128k -pix_fmt yuv420p output.mp4
ffmpeg version N-70239-g111d79a Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 4.9.2 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrw
b --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --
enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enab
le-zlib
libavutil 54. 19.100 / 54. 19.100
libavcodec 56. 26.100 / 56. 26.100
libavformat 56. 23.105 / 56. 23.105
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 11.101 / 5. 11.101
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
Input #0, avi, from 'input.avi':
Duration: 00:00:03.93, start: 0.000000, bitrate: 3255 kb/s
Stream #0:0: Video: msrle ([1][0][0][0] / 0x0001), pal8, 300x250, 3301 kb/s, 15 fps, 15 tbr, 15 tbn, 15 tbc
[libx264 @ 002ec860] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2
[libx264 @ 002ec860] profile High, level 2.2
[libx264 @ 002ec860] 264 - core 144 r2525 40bb568 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=1 ref=5 deblock=1:0:0 analyse=0x3:0x113 me=umh subm
e=8 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 i
nterlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=2 b_bias=0 direct=3 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=15 scenecut=40 intra_refresh=0 rc_lookahead=50 rc
=cbr mbtree=1 bitrate=500 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 vbv_maxrate=500 vbv_bufsize=1000 nal_hrd=none filler=0 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'output.mp4':
Metadata:
encoder : Lavf56.23.105
Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 576x480, q=-1--1, 500 kb/s, 15 fps, 15360 tbn, 15 tbc
Metadata:
encoder : Lavc56.26.100 libx264
Stream mapping:
Stream #0:0 -> #0:0 (msrle (native) -> h264 (libx264))
Press [q] to stop, [?] for help
frame= 59 fps= 30 q=-1.0 Lsize= 229kB time=00:00:03.80 bitrate= 493.5kbits/s
video:227kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.637976%
[libx264 @ 002ec860] frame I:3 Avg QP:26.53 size: 10657
[libx264 @ 002ec860] frame P:25 Avg QP:30.49 size: 5608
[libx264 @ 002ec860] frame B:31 Avg QP:32.26 size: 1935
[libx264 @ 002ec860] consecutive B-frames: 22.0% 16.9% 20.3% 40.7%
[libx264 @ 002ec860] mb I I16..4: 16.7% 69.0% 14.4%
[libx264 @ 002ec860] mb P I16..4: 11.1% 29.9% 3.8% P16..4: 21.3% 6.8% 2.6% 0.0% 0.0% skip:24.6%
[libx264 @ 002ec860] mb B I16..4: 1.7% 3.0% 0.3% B16..8: 29.7% 5.6% 0.8% direct: 2.1% skip:56.8% L0:50.5% L1:45.6% BI: 3.9%
[libx264 @ 002ec860] 8x8 transform intra:66.5% inter:79.4%
[libx264 @ 002ec860] direct mvs spatial:93.5% temporal:6.5%
[libx264 @ 002ec860] coded y,uvDC,uvAC intra: 40.3% 48.8% 25.7% inter: 12.4% 8.4% 1.4%
[libx264 @ 002ec860] i16 v,h,dc,p: 19% 59% 6% 17%
[libx264 @ 002ec860] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 10% 25% 16% 7% 8% 6% 11% 7% 10%
[libx264 @ 002ec860] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 20% 21% 9% 7% 9% 8% 10% 7% 10%
[libx264 @ 002ec860] i8c dc,h,v,p: 41% 33% 13% 13%
[libx264 @ 002ec860] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 002ec860] ref P L0: 67.6% 8.1% 9.6% 5.4% 6.6% 2.8%
[libx264 @ 002ec860] ref B L0: 84.6% 10.5% 3.9% 1.0%
[libx264 @ 002ec860] ref B L1: 95.9% 4.1%
[libx264 @ 002ec860] kb/s:472.20 -
-
How to expose new API methods in the HTTP Reporting API – Introducing the Piwik Platform
26 février 2015, par Thomas Steur — DevelopmentThis is the next post of our blog series where we introduce the capabilities of the Piwik platform (our previous post was How to write UI tests for your plugin). This time you’ll learn how to extend our Reporting API. For this tutorial you will need to have basic knowledge of PHP.
What is Piwik’s Reporting API ?
It allows third party applications to access analytics data and manipulate miscellaneous data (such as users or websites) through HTTP requests.
What is it good for ?
The Reporting API is used by the Piwik UI to render reports, to manage users, and more. If you want to add a feature to the Piwik UI, you might have to expose a method in the API to access this data. As the API is called via HTTP it allows you to fetch or manipulate any Piwik related data from anywhere. In these exposed API methods you can do pretty much anything you want, for example :
- Enhance existing reports with additional data
- Filter existing reports based on custom rules
- Access the database and generate custom reports
- Persist and read any data
- Request server information
Getting started
In this series of posts, we assume that you have already set up your development environment. If not, visit the Piwik Developer Zone where you’ll find the tutorial Setting up Piwik.
To summarize the things you have to do to get setup :
- Install Piwik (for instance via git).
- Activate the developer mode :
./console development:enable
. - Generate a plugin :
./console generate:plugin --name="MyApiPlugin"
. There should now be a folderplugins/MyApiPlugin
. - And activate the created plugin :
./console plugin:activate "MyApiPlugin"
Let’s start creating an API
We start by using the Piwik Console to create a new API :
./console generate:api
The command will ask you to enter the name of the plugin the created API should belong to. I will simply use the above chosen plugin name “MyApiPlugin”. There should now be a file
plugins/MyApiPlugin/API.php
which contains already an example to get you started easily :- class API extends \Piwik\Plugin\API
- {
- public function getAnswerToLife($truth = true)
- {
- if ($truth) {
- return 42;
- }
- return 24;
- }
- public function getExampleReport($idSite, $period, $date, $wonderful = false)
- {
- ));
- return $table;
- }
- }
Any public method in that file will be available via the Reporting API. For example the method
getAnswerToLife
can be called via this URL :index.php?module=API&method=MyApiPlugin.getAnswerToLife
. The URL parametermethod
is a combination of your plugin name and the method name within this class.Passing parameters to your method
Both example methods define some parameters. To pass any value to a parameter of your method simply specify them by name in the URL. For example
...&method=MyApiPlugin.getExampleReport&idSite=1&period=week&date=today&wonderful=1
to pass values to the parameters of the methodgetExampleReport
.Returning a value
In an API method you can return any boolean, number, string or array value. A resource or an object cannot be returned unless it implements the DataTableInterface such as DataTable (the primary data structure used to store analytics data in Piwik), DataTable\Map (stores a set of DataTables) and DataTable\Simple (a DataTable where every row has two columns : label and value).
Did you know ? You can choose the response format of your API request by appending a parameter
&format=JSON|XML|CSV|...
to the URL. Check out the Reporting API Reference for more information.Best practices
Check user permissions
Do not forget to check whether a user actually has permissions to access data or to perform an action. If you’re not familiar with Piwik’s permissions and how to check them read our User Permission guide.
Keep API methods small
At Piwik we aim to write clean code. Therefore, we recommend to keep API methods small (separation of concerns). An API pretty much acts like a Controller :
- public function createLdapUser($idSite, $login, $password)
- {
- Piwik::checkUserHasAdminAccess($idSite);
- $this->checkLogin($login);
- $this->checkPassword($password);
- $myModel = new LdapModel();
- $success = $myModel->createUser($idSite, $login, $password);
- return $success;
- }
This is not only easy to read, it will also allow you to create simple tests for
LdapModel
(without having to bootstrap the whole Piwik layer) and you will be able to reuse it in other places if needed.Calling APIs of other plugins
For example if you want to fetch an existing report from another plugin, say a list of all Page URLs, do not request this report by calling that method directly :
\Piwik\Plugins\Actions\API::getInstance()->getPageUrls($idSite, $period, $date);
. Instead, issue a new API request :
$report = \Piwik\API\Request::processRequest('Actions.getPageUrls', array(
'idSite' => $idSite,
'period' => $period,
'date' => $date,
));This has several advantages :
- It avoids a fatal error if the requested plugin is not available on a Piwik installation
- Other plugins can extend the called API method via events (adding additional report data to a report, doing additional permission checks) but those events will be only triggered when requesting the report as suggested
- If the method parameters change, your request will most likely still work
Publishing your Plugin on the Marketplace
In case you want to share your API with other Piwik users you can do this by pushing your plugin to a public GitHub repository and creating a tag. Easy as that. Read more about how to distribute a plugin and best practices when publishing a plugin.
Isn’t it easy to create a API ? We never even created a file ! If you have any feedback regarding our APIs or our guides in the Developer Zone feel free to send it to us.