Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1531415
  • 博文数量: 114
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 1357
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-19 18:13
文章分类
文章存档

2010年(8)

2009年(9)

2008年(27)

2007年(62)

2006年(8)

我的朋友

分类: LINUX

2007-08-21 21:49:10

北京理工大学 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
下载: 下载
阅读(7664) | 评论(12) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-01-23 11:29:01

建议用qt改进下