#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <dirent.h>
#include <signal.h>
#include <time.h>
/*-----------全局变量区------------*/
int log_fd; /*保存日志文件的文件描述符*/
#define LOG_FILE "/log.txt" /*日志文件存放的路径*/
DIR *video_dir_p=NULL; /*存放视频的目录: 打开的目录指针*/
int video_state=0;
#define VIDEO_FILE_PATH "/work/video_file/" //存放视频文件的目录
#define UPDATE_HOUR 16 //更新的时间: 小时
#define UPDATE_MIN 38 //更新的时间: 分钟
#define UPDATE_SEC 00 //更新的时间: 秒
/*-------函数声明---------*/
void DeleteListALLNode(void);
/*定义链表使用的结构体*/
struct VideoList
{
char *file_path;
struct VideoList *next;
};
/*链表头*/
struct VideoList *ListHead=NULL;
/*函数: 信号处理函数*/
void exit_sighandler(int sig)
{
/*1. 判断是什么信号*/
if(sig==2)
{
printf("用户终止了进程!\n");
}
else if(sig==11)
{
printf("进程访问了非法内存空间!\n");
}
/*2. 杀死父进程对应所有子进程*/
char cmd_buff[100];
//杀死父进程创建所有子进程,父进程本身不受影响
sprintf(cmd_buff,"pkill -9 -P %d",getpid());
system(cmd_buff);
sleep(2);
/*3. 关闭打开所有的文件或者目录*/
close(log_fd);
closedir(video_dir_p);
DeleteListALLNode();
/*4. 退出父进程*/
exit(1);
}
/*
函数功能: 获取本地时间,判断是否是否到达预设的时间
*/
void *Time_pthread_func(void *argv)
{
time_t time1;
time_t time2;
struct tm *system_time;
char cmd_buff[100];
while(1)
{
time1=time(NULL); //获取当前系统的时间秒单位
if(time1!=time2) //保证if每1秒进去一次
{
time2=time1;
system_time=localtime(&time1); //将秒单位时间,转成标准时间结构
printf("%d-%d-%d\n",system_time->tm_hour,system_time->tm_min,system_time->tm_sec);
/*更新的时间*/
if(system_time->tm_hour==UPDATE_HOUR
&& system_time->tm_min==UPDATE_MIN
&& system_time->tm_sec==UPDATE_SEC)
{
video_state=1; //表示进程需要终止
//"pkill -9 -P <父进程的PID>"
//杀死父进程创建所有子进程,父进程本身不受影响
sprintf(cmd_buff,"pkill -9 -P %d",getpid());
/*执行命令*/
system(cmd_buff);
printf("正在结束子进程!\n");
pthread_exit(NULL);
}
}
}
}
/*
函数功能: 扫描目录下的所有文件,加载到链表里
*/
void ScanDirFile()
{
struct dirent *dir_file;
struct VideoList *head_p=ListHead; //保存链表头的地址
struct VideoList *new_p=NULL;
while(dir_file=readdir(video_dir_p))
{
//过滤掉.和..
if(strcmp(dir_file->d_name,".")==0 || strcmp(dir_file->d_name,"..")==0)
{
continue;
}
//创建新节点
new_p=(struct VideoList*)malloc(sizeof(struct VideoList));
if(new_p==NULL)
{
printf("创建新节点空间申请错误!\n");
return;
}
//申请存放文件名称的空间
new_p->file_path=malloc(strlen(VIDEO_FILE_PATH)+strlen(dir_file->d_name)+1);
if(new_p->file_path==NULL)
{
printf("申请存放文件名称的空间错误!\n");
return;
}
//拼接路径
strcpy(new_p->file_path,VIDEO_FILE_PATH);
strcat(new_p->file_path,dir_file->d_name);
printf("播放的列表:%s\n",new_p->file_path);
//添加新的节点
while(head_p->next!=NULL)
{
head_p=head_p->next;
}
head_p->next=new_p;
new_p->next=NULL;
}
}
/*
函数功能: 删除链表节点
*/
void DeleteListALLNode(void)
{
struct VideoList *head_p=ListHead; //保存链表头的地址
struct VideoList *tmp_p;
struct VideoList *delete_p;
if(head_p!=NULL && head_p->next==NULL)
{
free(head_p); //释放链表头
}
else if(head_p->next!=NULL)
{
tmp_p=head_p->next;
free(head_p); //释放链表头
while(tmp_p->next!=NULL)
{
delete_p=tmp_p;
tmp_p=tmp_p->next;
free(delete_p->file_path);
free(delete_p);
}
free(tmp_p->file_path);
free(tmp_p);
}
}
int main(int argc,char **argv)
{
int pid;
int state=0;
struct VideoList *next_p=ListHead;
/*1. 注册将要捕获的信号*/
signal(SIGINT,exit_sighandler); /*进程终止信号:Ctrl+C*/
signal(SIGSEGV,exit_sighandler); /*进程访问了非法内存*/
/*2. 创建日志文件: 保存mplayer播放器的输出*/
log_fd=open(LOG_FILE,O_RDWR|O_CREAT,S_IRUSR|S_IWUSR);
/*3. 打开目录*/
video_dir_p=opendir(VIDEO_FILE_PATH);
if(video_dir_p==NULL)
{
printf("%s 存放视频的目录打开失败!\n",VIDEO_FILE_PATH);
exit(1);
}
/*4. 创建新的线程:判断更新时间*/
pthread_t threadID;
pthread_create(&threadID,NULL,Time_pthread_func,NULL);
pthread_detach(threadID); //设置分离属性
/*5. 遍历目录,更新链表*/
//创建链表头
ListHead=(struct VideoList*)malloc(sizeof(struct VideoList));
if(ListHead==NULL)
{
printf("链表头创建失败!\n");
exit(1);
}
ListHead->next=NULL; //下个节点为NULL
//扫描目录,并将目录下的文件添加到链表
ScanDirFile();
next_p=ListHead; //链表头
next_p=next_p->next; //取出数据节点
LOOP: //该标签表示继续播放下一个视频时,重复创建子进程
printf("正在播放视频名称:%s\n",next_p->file_path);
/*创建子进程*/
pid=fork();
/*子进程代码: mplayer播放器*/
if(pid==0)
{
/*将子进程的标准输出重定向到日志文件*/
dup2(log_fd,1);
/*启动子进程*/
execlp("mplayer","mplayer","-zoom","-x","800","-y","480","-slave","-quiet","-input","file=/mplayer_fifo",next_p->file_path,NULL);
}
/*父进程代码: 控制播放*/
else
{
/*等待子进程退出*/
wait(&state);
//判断是否需要结束当前进程
if(video_state==1)
{
/*执行外部脚本: 启动视频文件更新*/
system("./update_video.sh");
/*退出父进程*/
DeleteListALLNode();
close(log_fd);
closedir(video_dir_p);
exit(0);
}
/*遍历链表的下一个节点,取出文件名称,传递给子进程*/
if(next_p->next==NULL) //表示视频播放完毕
{
printf("视频播放完毕---->链表归位!\n");
next_p=ListHead; //链表头
next_p=next_p->next; //取出数据节点
}
next_p=next_p->next; //取出数据节点
/*再次启动子进程,播放下一个视频*/
goto LOOP;
}
return 0;
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
├─libmad高精度音频解码库源码 ├─Mplayer源码 ├─Tiny4412开发板声卡驱动 └─示例代码 ├─01 mplayer从模式使用示例 ├─02 mplayer循环播放指定目录下的文件 ├─03 dup2函数运用 ├─04 dup2函数实现日志记录功能 ├─05 wait函数运用-等待子进程退出 ├─06 exec系列函数使用示例 └─07 mplayer自动播放示例_模板代码
资源推荐
资源详情
资源评论
收起资源包目录
03 广告机完整代码.7z (7个子文件)
03 广告机完整代码
2.wmv 720KB
app 13KB
1.wmv 1.03MB
update_video.sh 759B
Makefile 100B
3.wmv 817KB
mplayer_app.c 6KB
共 7 条
- 1
资源评论
DS小龙哥
- 粉丝: 4w+
- 资源: 523
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功