1. 前言
廣告機(jī)是新一代的智能設(shè)備,通過(guò)終端軟件控制、網(wǎng)絡(luò)信息傳輸和多媒體終端顯示構(gòu)成一個(gè)完整的廣告播控系統(tǒng),并通過(guò)圖片、文字、視頻、小插件(天氣、匯率等)等多媒體素材進(jìn)行廣告宣傳。
廣告機(jī)最初的構(gòu)想是將廣告變被動(dòng)為主動(dòng),所以廣告機(jī)的互動(dòng)性使得它具備很多公共服務(wù)功能,并以此來(lái)吸引顧客主動(dòng)瀏覽廣告。
在城市里,廣告機(jī)大家應(yīng)該都不陌生,在地鐵、公交車、商場(chǎng)、銀行、廣場(chǎng)、電梯里很多人流量大的地方都有廣告機(jī),投放各種宣傳廣告。銀行的廣告機(jī)一般投放理財(cái)、貸款、活動(dòng)、利率一些信息,酒店的廣告機(jī)一般宣傳自己的酒店設(shè)施、配置;電梯、地鐵、公交車?yán)锏膹V告機(jī)主要是投放各個(gè)商家的廣告,比如:附近哪家火鍋店打折扣呀,飯店開(kāi)張呀、商家的新產(chǎn)品上市等等。
廣告機(jī)一般都是主動(dòng)播放視頻廣告,循環(huán)播放,用戶不能去主動(dòng)調(diào)整廣告機(jī)視頻,這篇文章就介紹如何利用Linux開(kāi)發(fā)板做一個(gè)廣告機(jī)項(xiàng)目,完成廣告機(jī)的主要功能。
廣告機(jī)主要是播放視頻,所以需要一個(gè)視頻播放器,上篇文章介紹了mplayer的交叉編譯,在Linux開(kāi)發(fā)板上已經(jīng)完成了視頻的播放,所以這篇文章就只是介紹在應(yīng)用層如何完成廣告機(jī)的邏輯代碼設(shè)計(jì)。
開(kāi)發(fā)板采用友善之臂的Tiny4412,板子上待遇聲卡設(shè)備也帶有現(xiàn)成的驅(qū)動(dòng),所以LCD屏的驅(qū)動(dòng)、聲卡驅(qū)動(dòng)都不用從頭開(kāi)發(fā),只需要注重應(yīng)用層開(kāi)發(fā)。
廣告機(jī)除了循環(huán)播放視頻以外,還需要實(shí)現(xiàn)網(wǎng)絡(luò)視頻更新,需要搭建一個(gè)服務(wù)器完成方便廣告機(jī)自動(dòng)下載最新的廣告視頻文件,自動(dòng)更新。
2. 項(xiàng)目實(shí)現(xiàn)代碼
播放器采用mplayer框架,mplayer支持主模式和從模式播放,為了方便控制mplayer,這里就采用從模式啟動(dòng)mplayer,也就是fork一個(gè)子進(jìn)程運(yùn)行mplayer的播放命令,完成視頻播放。主進(jìn)程里等待mplayer進(jìn)程視頻播放完畢完成新視頻切換,在主線程里還有一個(gè)線程,用來(lái)檢測(cè)服務(wù)器是否有新的視頻文件需要更新,然后在合適的時(shí)間進(jìn)行定時(shí)下載視頻文件。
#include
#include
#include
#include
#include
#include
#include
#include
#include
?
?
/**********************全局變量定義區(qū)*****************/
int fd_fifo; //創(chuàng)建有名管道,用于向mplayer發(fā)送命令
int fd_pipe[2]; //創(chuàng)建無(wú)名管道,用于從mplayer讀取命令
char DirName[100][100]; //存放視頻路徑
void listdir(char *argv,char *argv_famt); //遍歷目錄
int flag=0; //播放標(biāo)志
int VideoNum=0; //視頻總數(shù)量
//從鍵盤獲取將要寫入的命令
void *get_pthread(void *arg)
{
char buf[100];
char cmd[]="get_percent_pos\n";
int i=0;
while(1)
{
sleep(2);
if(write(fd_fifo,cmd,strlen(cmd))!=strlen(cmd))
{
perror("write error 1_!\n");
}
if(flag)
{
flag=0;
strcpy(buf,"loadfile ");
strcat(buf,DirName[i]);
strcat(buf,"\n\0");
//寫到播放器mplayer那一端
if(write(fd_fifo,buf,strlen(buf))!=strlen(buf))
perror("write error!\n"); //將命令寫入命名管道
i++;
if(i>=VideoNum)//判斷視頻文件是否到結(jié)尾
{
i=0;
}
}
}
}
?
void *print_pthread(void *arg)
{
char buf[100];
char num[3];
close(fd_pipe[1]); //關(guān)閉寫端。
int size=0;
int i=0;
while(1)
{
memset(buf,0,100);
size=read(fd_pipe[0],buf,sizeof(buf)); //從無(wú)名管道的寫端讀取信息打印在屏幕上
buf[size]='\0';
char *p=strstr(buf,"=");
if(p!=NULL)
{
num[0]=*(p+1);
num[1]=*(p+2);
if(atoi(num)>90)
{
flag=1; //切換視頻
printf("切換視頻......%d->\n",i);
}
}
printf("buf=%s \n",buf);
}
}
?
int main(int argc, char *argv[])
{
if(argc!=3)
{
printf("格式: ./app <目錄> <文件后綴>\n");
exit(-1);
}
int fd;
char buf[100];
pid_t pid;
unlink("/my_fifo");//如果命名管道存在,則先刪除
mkfifo("/my_fifo",O_CREAT|0666);
if (pipe(fd_pipe)<0 ) //創(chuàng)建無(wú)名管道 ?
? ? { ?
? ? ? ? ?perror("pipe error\n"); ?
? ? ? ? ?exit(-1); ?
? ? } ?
? ? ?//遍歷目錄
? ? ?listdir(argv[1],argv[2]); ?
? ? ?
? ? ?pid=fork();//創(chuàng)建進(jìn)程
? ? ?if(pid<0) ?
? ? { ?
? ? ? ? ?perror("fork"); ?
? ? } ?
? ? ?if(pid==0)//子進(jìn)程播放mplayer ?
? ? { ?
? ? ? ? ?close(fd_pipe[0]); ? ? ? ?//關(guān)閉讀
? ? ? ? ?dup2(fd_pipe[1],1); ? ? ? //將子進(jìn)程的標(biāo)準(zhǔn)輸出重定向到管道的寫端
? ? ? ? ?execl("/work/mplayer/MPlayer-1.3.0/_install/bin/mplayer","/work/mplayer/MPlayer-1.3.0/_install/bin/mplayer","-zoom","-x","800","-y","480","-slave","-quiet","-input","file=/my_fifo","1.wmv",NULL); ?
? ? } ?
? ? ?else ?
? ? { ?
? ? ? ? ?pthread_t tid1; ?
? ? ? ? ?pthread_t tid2; ?
? ? ? ? ?fd_fifo=open("/tmp/my_fifo",O_RDWR); ?
? ? ? ? ?if(fd<0) ?
? ? ? ? ? ? ?perror("open"); ?
? ? ? ? ? ? ? ?
? ? ? ? ?pthread_create(&tid1,NULL,get_pthread,NULL); ? ? ? ?//從鍵盤獲取控制信息 ?
? ? ? ? ?pthread_create(&tid2,NULL,print_pthread,NULL); ? ? ?//打印從無(wú)名管道收到的信息 ?
? ? ? ? ?pthread_join(tid1,NULL); ?
? ? ? ? ?pthread_join(tid2,NULL); ?
? ? } ?
? ? ?return 0; ?
?} ?
??
??
?//遍歷目錄
?void listdir(char *argv,char *argv_famt)
?{
? DIR *dir;
? ?//1.打開(kāi)目錄
? ?dir=opendir(argv);
? ?if(dir==NULL)
? {
? ? ? printf("目錄打開(kāi)失敗!\n");
? ? ? exit(-1);
? }
? ?
? ?//2. 讀取目錄
? ?struct dirent *dir_info;
? ?char *abs_address,*p; //絕對(duì)路徑
? ?int len;
? ?int i=0;
? ?while(dir_info=readdir(dir))
? {
? //字符串查找
? ? ? if(strstr(dir_info->d_name,argv_famt))
{
len=strlen(argv); //傳入的路徑長(zhǎng)度
len+=strlen(dir_info->d_name); //計(jì)算文件的名稱長(zhǎng)度
len+=1; //存放'\0'使用。
p=abs_address=malloc(len); //開(kāi)辟存放絕對(duì)路徑的空間
strcpy(abs_address,argv);//拷貝路徑
strcat(abs_address,dir_info->d_name);
strcpy(DirName[i++],abs_address); //存放路徑
free(p);
}
}
VideoNum=i;
//3. 關(guān)閉目錄
closedir(dir);
}
審核編輯:湯梓紅
-
Linux
+關(guān)注
關(guān)注
87文章
11215瀏覽量
208741 -
廣告機(jī)
+關(guān)注
關(guān)注
0文章
154瀏覽量
9741 -
開(kāi)發(fā)板
+關(guān)注
關(guān)注
25文章
4913瀏覽量
97086
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論