1. 前言
廣告機是新一代的智能設備,通過終端軟件控制、網絡信息傳輸和多媒體終端顯示構成一個完整的廣告播控系統,并通過圖片、文字、視頻、小插件(天氣、匯率等)等多媒體素材進行廣告宣傳。
廣告機最初的構想是將廣告變被動為主動,所以廣告機的互動性使得它具備很多公共服務功能,并以此來吸引顧客主動瀏覽廣告。
在城市里,廣告機大家應該都不陌生,在地鐵、公交車、商場、銀行、廣場、電梯里很多人流量大的地方都有廣告機,投放各種宣傳廣告。銀行的廣告機一般投放理財、貸款、活動、利率一些信息,酒店的廣告機一般宣傳自己的酒店設施、配置;電梯、地鐵、公交車里的廣告機主要是投放各個商家的廣告,比如:附近哪家火鍋店打折扣呀,飯店開張呀、商家的新產品上市等等。
廣告機一般都是主動播放視頻廣告,循環播放,用戶不能去主動調整廣告機視頻,這篇文章就介紹如何利用Linux開發板做一個廣告機項目,完成廣告機的主要功能。
廣告機主要是播放視頻,所以需要一個視頻播放器,上篇文章介紹了mplayer的交叉編譯,在Linux開發板上已經完成了視頻的播放,所以這篇文章就只是介紹在應用層如何完成廣告機的邏輯代碼設計。
開發板采用友善之臂的Tiny4412,板子上待遇聲卡設備也帶有現成的驅動,所以LCD屏的驅動、聲卡驅動都不用從頭開發,只需要注重應用層開發。
廣告機除了循環播放視頻以外,還需要實現網絡視頻更新,需要搭建一個服務器完成方便廣告機自動下載最新的廣告視頻文件,自動更新。
2. 項目實現代碼
播放器采用mplayer框架,mplayer支持主模式和從模式播放,為了方便控制mplayer,這里就采用從模式啟動mplayer,也就是fork一個子進程運行mplayer的播放命令,完成視頻播放。主進程里等待mplayer進程視頻播放完畢完成新視頻切換,在主線程里還有一個線程,用來檢測服務器是否有新的視頻文件需要更新,然后在合適的時間進行定時下載視頻文件。
#include
#include
#include
#include
#include
#include
#include
#include
#include
?
?
/**********************全局變量定義區*****************/
int fd_fifo; //創建有名管道,用于向mplayer發送命令
int fd_pipe[2]; //創建無名管道,用于從mplayer讀取命令
char DirName[100][100]; //存放視頻路徑
void listdir(char *argv,char *argv_famt); //遍歷目錄
int flag=0; //播放標志
int VideoNum=0; //視頻總數量
//從鍵盤獲取將要寫入的命令
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)//判斷視頻文件是否到結尾
{
i=0;
}
}
}
}
?
void *print_pthread(void *arg)
{
char buf[100];
char num[3];
close(fd_pipe[1]); //關閉寫端。
int size=0;
int i=0;
while(1)
{
memset(buf,0,100);
size=read(fd_pipe[0],buf,sizeof(buf)); //從無名管道的寫端讀取信息打印在屏幕上
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 ) //創建無名管道 ?
? ? { ?
? ? ? ? ?perror("pipe error\n"); ?
? ? ? ? ?exit(-1); ?
? ? } ?
? ? ?//遍歷目錄
? ? ?listdir(argv[1],argv[2]); ?
? ? ?
? ? ?pid=fork();//創建進程
? ? ?if(pid<0) ?
? ? { ?
? ? ? ? ?perror("fork"); ?
? ? } ?
? ? ?if(pid==0)//子進程播放mplayer ?
? ? { ?
? ? ? ? ?close(fd_pipe[0]); ? ? ? ?//關閉讀
? ? ? ? ?dup2(fd_pipe[1],1); ? ? ? //將子進程的標準輸出重定向到管道的寫端
? ? ? ? ?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); ? ? ?//打印從無名管道收到的信息 ?
? ? ? ? ?pthread_join(tid1,NULL); ?
? ? ? ? ?pthread_join(tid2,NULL); ?
? ? } ?
? ? ?return 0; ?
?} ?
??
??
?//遍歷目錄
?void listdir(char *argv,char *argv_famt)
?{
? DIR *dir;
? ?//1.打開目錄
? ?dir=opendir(argv);
? ?if(dir==NULL)
? {
? ? ? printf("目錄打開失敗!\n");
? ? ? exit(-1);
? }
? ?
? ?//2. 讀取目錄
? ?struct dirent *dir_info;
? ?char *abs_address,*p; //絕對路徑
? ?int len;
? ?int i=0;
? ?while(dir_info=readdir(dir))
? {
? //字符串查找
? ? ? if(strstr(dir_info->d_name,argv_famt))
{
len=strlen(argv); //傳入的路徑長度
len+=strlen(dir_info->d_name); //計算文件的名稱長度
len+=1; //存放'\0'使用。
p=abs_address=malloc(len); //開辟存放絕對路徑的空間
strcpy(abs_address,argv);//拷貝路徑
strcat(abs_address,dir_info->d_name);
strcpy(DirName[i++],abs_address); //存放路徑
free(p);
}
}
VideoNum=i;
//3. 關閉目錄
closedir(dir);
}
審核編輯:湯梓紅
-
Linux
+關注
關注
87文章
11229瀏覽量
208927 -
廣告機
+關注
關注
0文章
154瀏覽量
9754 -
開發板
+關注
關注
25文章
4945瀏覽量
97199
發布評論請先 登錄
相關推薦
評論