读书人

[请问] linux C/C++, 使用libflashpla

发布时间: 2012-03-29 12:53:12 作者: rapoo

[请教] linux C/C++, 使用libflashplayer.so, 控制flash文件的播放
各位高手,请教一下。

我现在需要在Linux下实现一个简单的应用程序,用来控制flash文件的播放。编程语言C/C++。

通过网上查找资料,我现在是使用Adobe的libflashplayer.so库。通过阅读mozilla-sdk相关的源码,对该库的使用有了一定的了解,
程序基本写完,但是运行时,总是产生段错误,发现是在调用NPPluginFuncs的函数时(如setwindow, newstream等),出错,
不知是传参有问题,还是其他的问题。

下面是我现在的代码:

foo.c

C/C++ code
#define MIN(a,b) ((a) <= (b) ? (a) : (b))#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <dlfcn.h>#include <gtk/gtk.h>#include <gdk/gdkx.h>#include "npapi.h"#include "npupp.h"static void *handle;static GtkWidget *window;static GtkWidget *socket;/*  plugin meta member functions  */char* (*gNP_GetMIMEDescription)(void);NPError (*gNP_Initialize)(NPNetscapeFuncs* aNPNFuncs, NPPluginFuncs* aNPPFuncs);NPError (*gNP_GetValue)(void* future, NPPVariable variable, void *value);NPError (*gNP_Shutdown)(void);/* Create a new plugin instance, passing some very basic arguments */static NPError CallNew(NPPluginFuncs *NPPFuncs, NPP plugin, char *swf_file, int width, int height){    NPError err = NPERR_NO_ERROR;    char width_s[8];    char height_s[8];    int16 argc = 5;    char* argn[5];    char* argv[5];    NPBool xembed;    sprintf(width_s, "%d", width);    sprintf(height_s, "%d", height);    argn[0] = "SRC";    argn[1] = "WIDTH";    argn[2] = "HEIGHT";    argn[3] = "MENU";    argn[4] = "LOOP";    argv[0] = swf_file;    argv[1] = width_s;    argv[2] = height_s;    argv[3] = "FALSE";    argv[4] = "TRUE";#ifdef DEBUG    printf("swf_file: %s, width_s: %s, height_s: %s\n",        swf_file, width_s, height_s);#endif //DEBUG    NPPFuncs->newp("application/x-shockwave-flash:swf:Shockwave Flash", \        plugin, NP_EMBED, argc, argn, argv, NULL);    xembed = true;    err = NPPFuncs->getvalue(plugin, NPPVpluginNeedsXEmbed, &xembed);    if(err != NPERR_NO_ERROR)        fprintf(stderr, "ouch\n");    return err;}/* Create a new Xt window and pass it to the plugin. */static NPError CallSetWindow(NPPluginFuncs *NPPFuncs, NPP plugin, int width, int height){    NPSetWindowCallbackStruct ws_info;    NPWindow win;    GdkDrawable *draw = (GdkDrawable *)(socket->window);    Window window = GDK_DRAWABLE_XID(draw);        memset(&ws_info, 0, sizeof(NPSetWindowCallbackStruct));    memset(&win, 0, sizeof(NPWindow));    ws_info.type = NP_SETWINDOW;    ws_info.display = GDK_DRAWABLE_XDISPLAY(draw);    ws_info.visual = GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(draw));    ws_info.colormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(draw));    ws_info.depth = gdk_drawable_get_depth(draw);    win.type = NPWindowTypeDrawable;    win.x = 0;    win.y = 0;    win.width = width;    win.height = height;    win.ws_info = &ws_info;    win.window = &window;    //here out "segment fault"!!!    //NPPFuncs->setwindow(plugin, &win);}//* Open, read, and write the contents of swf_file to the plugin instance. */static NPError SendSrcStream(NPPluginFuncs *NPPFuncs, NPP plugin, char *swf_file){    NPError err = NPERR_NO_ERROR;    NPMIMEType type = "application/x-shockwave-flash";    struct stat buf; //file state struct    NPStream stream;    uint16 stype = 0;    FILE *swf_fd;    char data[1024*10+1];    int write_idx, write_max;    int bytes_read, bytes_written;    char *pfn;    NPError reason;    memset(&stream, 0, sizeof(NPStream));    if(access(swf_file, F_OK) != 0)        return NPERR_FILE_NOT_FOUND;    int fd = open(swf_file, O_RDONLY);    fstat(fd, &buf);    stream.url = swf_file;    stream.end = buf.st_size;    stream.lastmodified = buf.st_mtime;    //segment default    //NPPFuncs->newstream(plugin, type, &stream, TRUE, &stype);    //if(err != NPERR_NO_ERROR)    //    return err;#ifdef DEBUG                printf("test newstream : success!\n");#endif //DEBUG    if((stype == NP_NORMAL) || (stype == NP_ASFILE)) {        swf_fd = fopen(swf_file, "r");        write_idx = 0;        while(stream.end > 0) {            //write_max = NPPFuncs->writeready(plugin, &stream);#ifdef DEBUG                                    printf("NPP_WriteReady: write_max = %d, end = %d\n", \                    write_max, stream.end);#endif //DEBUG            if(write_max <= 0) break;            bytes_read = MIN(sizeof(data), stream.end);            bytes_read = fread(data, sizeof(data), bytes_read, swf_fd);#ifdef DEBUG                                    printf("fread: bytes_read = %d\n", bytes_read);#endif //DEBUG            //bytes_written = NPPFuncs->write(plugin, \                &stream, write_idx, \                bytes_read, \                &data);#ifdef DEBUG                                    printf("NPP_Write: offset = %d, end = %d, " \                    "written = %d\n", write_idx, stream.end,                    bytes_read);#endif //DEBUG            if(bytes_written <= 0) break;            write_idx += bytes_written;            stream.end -= bytes_written;        }        fclose(swf_fd);    }    if((stype == NP_ASFILE) || (stype == NP_ASFILEONLY)) {        if(stream.end == 0) pfn = swf_file;        else pfn = NULL;        //NPPFuncs->asfile(plugin, &stream, pfn);    }    if(stype != NP_SEEK) {        if(stream.end == 0) reason = NPRES_DONE;        else reason = NPRES_NETWORK_ERR;        //segment default        //err = NPPFuncs->destroystream(plugin, &stream, reason);    }    return err;}void LoadFlashPlugin(){    handle = dlopen ("libflashplayer.so", RTLD_LAZY);    if (!handle) {        fprintf (stderr, "%s\n", dlerror());        exit(1);    }    gNP_GetMIMEDescription = dlsym(handle, "NP_GetMIMEDescription");    gNP_Initialize = dlsym(handle, "NP_Initialize");    gNP_GetValue = dlsym(handle, "NP_GetValue");    gNP_Shutdown = dlsym(handle, "NP_Shutdown");    dlerror();    /* Clear any existing error */}NPError PlaySwf(NPP plugin, char *swf_file, int width, int height){    NPError rv = NPERR_NO_ERROR;    NPNetscapeFuncs NPNFuncs;    NPPluginFuncs NPPFuncs;    rv = (*gNP_Initialize)(&NPNFuncs, &NPPFuncs);    if(rv != NPERR_NO_ERROR)        printf("NP_Initialize result = %d\n", rv);    rv = CallNew(&NPPFuncs, plugin, swf_file, width, height);    if(rv != NPERR_NO_ERROR)        printf("NPP_NewProc result = %d\n", rv);    rv = CallSetWindow(&NPPFuncs, plugin, width, height);    if(rv != NPERR_NO_ERROR)        printf("NPP_SetWindow result = %d\n", rv);    rv = SendSrcStream(&NPPFuncs, plugin, swf_file);    if(rv != NPERR_NO_ERROR)        printf("Writing SWF file, result = %d\n", rv);    return NPERR_NO_ERROR;}void InitializeGtk(int width, int height){    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);    gtk_signal_connect(GTK_OBJECT(window),            "delete_event",            G_CALLBACK(gtk_main_quit),            NULL);    gtk_window_set_title(GTK_WINDOW(window), "flashplayer");    gtk_container_set_border_width(GTK_CONTAINER(window), 10);    gtk_widget_set_size_request(window, width, height);    socket = gtk_socket_new();    gtk_widget_show (socket);    gtk_container_add(GTK_CONTAINER(window), socket);    gtk_widget_show (window);}int main(int argc, char **argv) {    char *swf_file = "CS_startup.swf";    int width = 700;    int height = 400;    NPP plugin;        gtk_init(&argc, &argv);        LoadFlashPlugin();        InitializeGtk(width, height);    /*  NP_GetMIMEDescription  */    printf("%s\n", (*gNP_GetMIMEDescription)());    PlaySwf(plugin, swf_file, width, height);        gtk_main();    /*  NP_Shutdown  */    (*gNP_Shutdown)();    dlclose(handle);    return 0;} 



Makefile


[解决办法]
你的NPNFuncs列表里的函数在哪里赋值的?他们是flashplayer.so能供work的基础。
[解决办法]
mark帮顶
[解决办法]
#include "npapi.h"
#include "npupp.h"

这两个文件没找到阿,我用的是fc10,能不能发给我整个工程或这两个文件(还有他们相关的文件),邮箱sunjianpin@sina.com.cn

十分感谢
[解决办法]
如果是有声音的SWF文件呢。。。 反正我用的FLASH播放器就没播放正常过。。 压根放不出来--外国语教程来着。。。
[解决办法]
你好,工程已收到,谢谢
不过编译过程出错,
/usr/bin/ld: cannot find -lflashplayer
collect2: ld return 1 exit status
make: *** [all] Error 1

这个应该怎么处理阿
[解决办法]
LZ搞定没? 还是给你提个初始化是可能出现的问题。NPP在这里是个指针,不是一个struct, 所以需要你给它提前分配内存,NPP plugin = malloc...
[解决办法]
能否分享一下楼主的代码?


[解决办法]
lz,我编译通过了,也运行了,但是界面上什么东西也没有,不知道为什么,你自己的运行成功了吗
[解决办法]
先请教一下:就是如果你/我成功在gtk上加载了flash插件,且能正确的加载swf文件,那么与swf如果实现通信呢?
windows上有CallFunction,回调有fscommand以及flashcall,当然这都得益与adobe在(IE)插件提供的com接口,
当然,在网页中可以通过js与swf交互,包括回调。
我的疑问:如果是自己加载,与swf通信该如何做?

愿意分享的话: jengju@gmail.com
非常乐意贡献自己的一点力
[解决办法]
楼主,我也在做和你一样的工作,一起交流一下吧
Netscape Client Plugin API和libflashplayer是什么关系啊?
我觉得NPNFuncs是flash的回调函数,你自己实现了提供给libflashplayer用的,不应该是由你来调用的
如果要向flashplayer提供流,应该是libflashplayer API的函数才是

分享一下工程吧,谢谢 frankpzh@gmail.com

读书人网 >UNIXLINUX

热点推荐