基於live555實現實時視訊監控
目錄
QQ:809205580
1 所需軟體、原始碼及下載地址
[email protected]:/home/work#tar zxvf live555-latest.tar.gz
[email protected]:/home/work#cd live
[email protected]:/home/work/live#./genMakefiles linux
[email protected]:/home/work/live#make
[email protected]:/home/work/live#ls mediaServer/
live555MediaServer
3.1 原始碼
encoding.c
#include<math.h>
#include<libavutil/opt.h>
#include<libavcodec/avcodec.h>
#include<libavutil/imgutils.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<errno.h>
#include<signal.h>
intstop = 0;
constchar *FIFO = "test.264";
/*
* Video encoding example
*/
staticvoid video_encode_example(const char *filename, int codec_id)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int i, ret, x, y, got_output;
FILE *f;
AVFrame *frame;
AVPacket pkt;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
printf("Encode video file %s\n",filename);
/* find the mpeg1 video encoder */
codec = avcodec_find_encoder(codec_id);
if (!codec)
{
fprintf(stderr, "Codec notfound\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c)
{
fprintf(stderr, "Could notallocate video codec context\n");
exit(1);
}
/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
c->time_base= (AVRational){1,25};
c->gop_size = 10; /* emit one intraframe every ten frames */
c->max_b_frames=1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
if(codec_id == AV_CODEC_ID_H264)
av_opt_set(c->priv_data,"preset", "slow", 0);
/* open it */
if (avcodec_open2(c, codec, NULL) < 0)
{
fprintf(stderr, "Could not opencodec\n");
exit(1);
}
f = fopen(filename, "w");
if (!f)
{
fprintf(stderr, "Could not open%s\n", filename);
exit(1);
}
frame = avcodec_alloc_frame();
if (!frame)
{
fprintf(stderr, "Could notallocate video frame\n");
exit(1);
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
/* the image can be allocated by any meansand av_image_alloc() is
* just the most convenient way ifav_malloc() is to be used */
ret = av_image_alloc(frame->data,frame->linesize, c->width, c->height, c->pix_fmt, 32);
if (ret < 0)
{
fprintf(stderr, "Could notallocate raw picture buffer\n");
exit(1);
}
/* encode time second of video */
i = 0;
while (!stop)
{
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by theencoder
pkt.size = 0;
fflush(stdout);
/* prepare a dummy image */
/* Y */
for(y=0;y<c->height;y++) {
for(x=0;x<c->width;x++) {
frame->data[0][y *frame->linesize[0] + x] = x + y + i * 3;
}
}
/* Cb and Cr */
for(y=0;y<c->height/2;y++) {
for(x=0;x<c->width/2;x++) {
frame->data[1][y *frame->linesize[1] + x] = 128 + y + i * 2;
frame->data[2][y *frame->linesize[2] + x] = 64 + x + i * 5;
}
}
frame->pts = i;
/* encode the image */
ret = avcodec_encode_video2(c,&pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Errorencoding frame\n");
exit(1);
}
if (got_output) {
printf("Write frame %3d (size=%5d)\n",i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
i++;
}
/* get the delayed frames */
for (got_output = 1; got_output; i++) {
fflush(stdout);
ret = avcodec_encode_video2(c,&pkt, NULL, &got_output);
if (ret < 0) {
fprintf(stderr, "Errorencoding frame\n");
exit(1);
}
if (got_output) {
printf("Write frame %3d(size=%5d)\n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
/* add sequence end code to have a realmpeg file */
fwrite(endcode, 1, sizeof(endcode), f);
fclose(f);
avcodec_close(c);
av_free(c);
av_freep(&frame->data[0]);
avcodec_free_frame(&frame);
printf("\n");
}
voidhandle(int sig)
{
if (sig == SIGINT)
stop = 1;
}
intmain(int argc, char **argv)
{
signal(SIGINT, handle);
signal(SIGPIPE, SIG_IGN);
/* register all the codecs */
avcodec_register_all();
if (mkfifo(FIFO, 0644)< 0)
{
if (EEXIST != errno)
{
perror("mkfifo");
exit(1);
}
}
video_encode_example(FIFO,AV_CODEC_ID_H264);
return 0;
}
將encoding.c拷貝到ffmpeg原始碼目錄的ffmpeg-1.1/doc/examples目錄下,進入該目錄,修改Makefile
EXAMPLES= decoding_encoding \
demuxing \
filtering_video \
filtering_audio \
metadata \
muxing \
resampling_audio \
scaling_video \
encoding
然後執行make將生成可執行檔案encoding
vod.html
<!DOCTYPEhtml PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<htmlxmlns="http://www.w3.org/1999/xhtml" >
<head>
<metahttp-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script>
var itemId = 0;
function getVLC(name)
{
if(window.document[name])
{
returnwindow.document[name];
}
if(navigator.appName.indexOf("Microsoft Internet")== -1)
{
if (document.embeds&& document.embeds[name])
return document.embeds[name];
}
else
{
returndocument.getElementById(name);
}
}
function doAddPlaylist()
{
var vlc =getVLC("vlc");
itemId=vlc.playlist.add("rtsp://192.168.230.141/test.264");
document.getElementById("btn_stop").disabled= false;
}
</script>
</head>
<bodyonload="doAddPlaylist()">
<div>
<objectclassid="clsid:9be31822-fdad-461b-ad51-be1d1c159921"
width="352"
height="288"
id="vlc"
events="true">
<paramname="mrl" value="rtsp://192.168.230.141/test.264" />
<paramname="showdisplay" value="true" />
<paramname="autoloop" value="false" />
<paramname="autoplay" value="false" />
<paramname="volume" value="50" />
<paramname="starttime" value="0" />
<embedpluginspage="http://www.videolan.org"
type="application/x-vlc-plugin"
version="videolan.vlcplugin.2"
width="352"
height="288"
name="vlc">
</embed>
</object>
</div>
</body>
</html>
5 執行
在Linux系統中建立工作目錄
[email protected]:/home/work#mkdir video
[email protected]:/home/work#cd video/
拷貝上面編譯生成的live555MediaServer到當前目錄
[email protected]:/home/work/video#cp /home/work/live/mediaServer/live555MediaServer .
拷貝上面編譯生成的encoding到當前目錄
[email protected]:/home/work/video#cp /home/work/ffmpeg-1.1/doc/examples/encoding .
執行encoding
[email protected]:/home/work/video#./encoding
Encodevideo file test.264
[[email protected] 0x8bcf020] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE4.2 AVX
[[email protected] 0x8bcf020] profile High, level 1.3
在開一個終端,並進入到/home/work/video目錄,執行live555MediaServer
[email protected]:/home/work/video#./live555MediaServer
LIVE555Media Server
version 0.78 (LIVE555 Streaming Medialibrary version 2013.12.16).
Playstreams from this server using the URL
rtsp://192.168.230.141/<filename>
where<filename> is a file present in the current directory.
Eachfile's type is inferred from its name suffix:
".264" => a H.264 VideoElementary Stream file
".aac" => an AAC Audio(ADTS format) file
".ac3" => an AC-3 Audiofile
".amr" => an AMR Audiofile
".dv" => a DV Video file
".m4e" => a MPEG-4 VideoElementary Stream file
".mkv" => a Matroskaaudio+video+(optional)subtitles file
".mp3" => a MPEG-1 or 2Audio file
".mpg" => a MPEG-1 or 2Program Stream (audio+video) file
".ts" => a MPEG TransportStream file
(a ".tsx" indexfile - if present - provides server 'trick play' support)
".vob" => a VOB (MPEG-2video with AC-3 audio) file
".wav" => a WAV Audio file
".webm" => a WebMaudio(Vorbis)+video(VP8) file
Seehttp://www.live555.com/mediaServer/ for additional documentation.
(Weuse port 80 for optional RTSP-over-HTTP tunneling, or for HTTP live streaming(for indexed Transport Stream files only).)
將vod.html中的IP修改為上面的紅色部分,雙擊vod.html
單擊播放按鈕(將滑鼠停靠在播放器窗口裡就會出現控制按鈕)
現在已經開始實時監控了。只不過伺服器程式發來的只是簡單的手動製作的影象。對encoding.c稍加修改,新增v4l2相關程式碼,就可以實現對攝像頭的實時視訊監控。
from: http://blog.csdn.net/zjhsucceed_329/article/details/17552801