北京理工大学 20981 陈罡
linux的世界真是精彩啊,只要掌握了基本的工具————gcc,就可以做很多很多事情。
在open source的世界里,真的如同文化大革命一样“人有多大胆,地有多大产”,
只有你想不到的没有你做不到的。一个朋友偶然提起说nokia手机可以播放flash文件,
而moto的手机就不行,这一下子把我不服输的心思激发起来了。凭什么linux手机就
不行?于是开始查找和收集资料,呵呵,还真是好运啊,找到了e680手机上的播放
flash文件的源代码。这下子可是帮了我大忙,可以站在巨人的肩膀上了,在这里,
要“缅怀”一下巨人的风采:flash lib,原作者为:
Olivier Debon <>
Fabrice Bellard <>
作者真的是非常谦逊,在feature里面只写了limitation:
Features:
Limitations :
- The plugin and the player use XShm extensions, so remote display is not possible.
- No Flash 4 features (but no crash on Flash 4 files).
Not functional :
- No Morphing.
- No vertical anti-aliasing.
SOUND SUPPORT:
Limitations :
- No streamed sound supported (interleaved data).
- No sound envelop. So no fading or balancing effect.
But the main feature is here and sound can be enjoyed.
I recommend OSS drivers, but it is not required at all
经过我测试flash 4.0版本的swf是可以正常播放的,这个声音的支持,倒不是谦虚,确实
不尽如人意,只能够支持raw和adpcm两种格式,呵呵,有时间把mp3解码也加入进去吧。
这只是linux平台的flash lib,把它移植,并在e680上运行起来的是。。。不太清楚他
叫什么名字,这里还是老老实实把uri贴出来吧:
总之,很感谢这个作者,没有他的工作,我不可能在一个小时之内就让falsh在手机上跑起来。
贴出代码如下:
#include
#include
#include "flash.h" //这个就是flash的库的引用文件
#include "ezfb.h" //这个是我写的a1200直接写屏库,可以在motorolafans找到
#define SWF_PATHNAME "a.swf" //这个是要播放的flash文件
#define IMG_WIDTH 240
#define IMG_HEIGHT 197
struct ezfb fb = {0} ;
//用于获取flash中的uri
void show_uri(char *url, char *target, void *client_data)
{
printf("flash uri : %s\n", url);
}
//用于缓冲区播放完毕后,继续载入flash数据
void get_swf(char *url, int level, void *client_data)
{
FlashHandle flashHandle;
flashHandle = (FlashHandle) client_data;
printf("load movie : %s @ %d\n", url, level);
}
//显示当前flash的信息
void show_flash_info(const char * filename, struct FlashInfo * info)
{
printf("flash name : %s\n", filename) ;
// 显示flash的版本号
printf("flash version : %d\n", info->version) ;
// 显示当前flash的帧数
printf("flash frames : %d\n", info->frameCount) ;
// 显示当前flash播放的帧率,也就是fps
printf("flash rate : %d\n", info->frameRate) ;
}
// 这里是把整个flash文件读入内存中,比较浪费了,应该可以
// 有更好方法来支持大的flash文件播放
int read_file(const char *filename, char **buffer, long *size)
{
FILE *in;
char *buf;
long length;
in = fopen(filename,"r");
if (in == 0) {
perror(filename);
return -1;
}
fseek(in,0,SEEK_END);
length = ftell(in);
rewind(in);
buf = (char*) malloc(length);
fread(buf,length,1,in);
fclose(in);
*size = length;
*buffer = buf;
return length;
}
int main(int argc, char * argv[])
{
FlashHandle flash_handle ;
struct FlashInfo flash_info ;
struct FlashDisplay flash_disp ;
long flash_cmd = FLASH_WAKEUP ;
int flash_frame_count ;
int flash_delay ;
struct timeval flash_tv ;
struct timeval old_time ;
struct timeval cur_time ;
int passed_ms = 0 ;
char * swf_buffer = NULL ;
long swf_size = 0 ;
u_short * img565 ;
int ret ;
// 读入swf文件
ret = read_file(SWF_PATHNAME, &swf_buffer, &swf_size) ;
if(ret < 0) {
printf("swf file : %s open failed!\n", SWF_PATHNAME) ;
exit(-1) ;
}
// 创建flash播放的句柄
flash_handle = FlashNew() ;
if(flash_handle == 0) {
printf("create flash handle failed!\n") ;
if(swf_buffer) free(swf_buffer) ;
exit(-2) ;
}
// 解析flash文件,其实就是把头数据部分提取出来
do {
ret = FlashParse(flash_handle, 0, swf_buffer, swf_size);
} while (ret & FLASH_PARSE_NEED_DATA);
free(swf_buffer);
// 显示flash的信息
FlashGetInfo(flash_handle, &flash_info) ;
show_flash_info(SWF_PATHNAME, &flash_info) ;
// 初始化屏幕部分
ezfb_init(&fb) ;
// 这里我们让flash lib的输出16位565的rgb图像
img565 = new u_short [IMG_WIDTH * IMG_HEIGHT] ;
flash_disp.pixels = (char *)(img565) ;
flash_disp.width = IMG_WIDTH ;
flash_disp.height = IMG_HEIGHT ;
flash_disp.bpl = IMG_WIDTH * 2 ;
flash_disp.depth = 16 ; // 色深16位
flash_disp.bpp = 2 ; // 这里的bpp是指大B,Byte字节
FlashGraphicInit(flash_handle, &flash_disp) ;
// 初始化声音设备,a1200为/dev/dsp或者/dev/dsp16
FlashSoundInit(flash_handle, "/dev/dsp") ;
// 注册回调函数
FlashSetGetUrlMethod(flash_handle, show_uri, 0);
FlashSetGetSwfMethod(flash_handle, get_swf, (void*)flash_handle);
// 开始播放flash
flash_frame_count = 0 ;
gettimeofday(&cur_time, 0) ;
old_time = cur_time ;
while(flash_frame_count++ < flash_info.frameCount) {
FlashExec(flash_handle, flash_cmd, 0, &flash_tv) ;
gettimeofday(&cur_time, 0);
flash_delay = (flash_tv.tv_usec-cur_time.tv_usec)/1000 ;
flash_delay += (flash_tv.tv_sec-cur_time.tv_sec)*1000 ;
flash_delay = (flash_delay < 0) ? 20 : flash_delay ;
// 保证播放延时
do {
sleep(0) ;
gettimeofday(&cur_time, 0);
if(old_time.tv_usec > cur_time.tv_usec) {
cur_time.tv_usec += 1000000 ;
cur_time.tv_sec-- ;
}
passed_ms = (cur_time.tv_usec - old_time.tv_usec)/1000 ;
passed_ms += (cur_time.tv_sec - old_time.tv_sec)*1000 ;
}while(passed_ms < flash_delay) ;
old_time = cur_time ;
ezfb_blt_screen(&fb,
(u_char *)(img565),
MODE_BPP16,
0, 0,
IMG_WIDTH, IMG_HEIGHT) ;
}
delete img565 ;
ezfb_release(&fb) ;
// 释放flash句柄
FlashClose(flash_handle) ;
return 0 ;
}
以下是在手机中的真机抓图:
下面是编译好的fl和测试flash文件。欢迎有兴趣的朋友下载,测试,只需要把下面两个文件
拷贝到手机的/mmc/mmca1/目录下面,通过eKonsole运行,或者telnet运行。
|
文件: |
flash.rar |
大小: |
117KB |
下载: |
下载 | |
阅读(7669) | 评论(12) | 转发(0) |