Project1

标题: RM视频播放器 [2011-4-20更新异步模式 可以融合进 RM 画面] [打印本页]

作者: zh99998    时间: 2010-11-27 14:47
标题: RM视频播放器 [2011-4-20更新异步模式 可以融合进 RM 画面]
独占模式:


异步模式:


  演示包: video_full.rar (7.24 MB, 下载次数: 22234) (核心版本: 2.0.0418)
    (包含程序核心,MP4编码库,一个测试用的视频)
  
  核心: Video(Ver 3.0.0420).rar (1.41 MB, 下载次数: 7994) (04-20更新,视频与RM画面共存)
  MP4编码库:http://u.115.com/file/f43246b71e (04-20更新)
  RMVB编码库: https://rpg.blue/forum.php?mod=a ... jE5MDcwN3wwfA%3D%3D (04-18更新)
注意: 新版本添加对MP4 RMVB格式的支持,有什么其他格式的视频需要添加支持的, 需要请回帖或PM我,将会优先更新您需要的格式, 此外, 其他的视频格式能不能播放需要取决于电脑上有没有相对应的解码库.

使用方法: 请看脚本之前的 FSL 使用方法.然后在下载程序核心包, 解码包. 将解码包里的 dll 都解压到 VideoData 文件夹里就可以了.
  1. $scene = Scene_Video.new(file_name, layer, x, y, width, height, type, playing, play_mode)
  2. #         其中:
  3. #         file_name(String)         : 文件名
  4. #         layer(int)                : 加载层数
  5. #         x, y, width. height(int)  : 播放画布范围定义.
  6. #         type(int)                 : 返回类型 0 Scene_Title; 1 Scene_Map
  7. #         playing(bool)             : 播放开始类型 true 立即播放; false 手动播放
  8. #         play_mode(bool)           : 播放模式 true 独占模式; false 异步模式
复制代码
旧版本:http://rpg.blue/upload_program/goods/video.rar
附带25MB的福利(雾)

进阶功能说明(基本上都包含在脚本 RmVideoPlayer 里):
set_audio_balance(balance) :                         设置 声道参数, balance 在 –10000(左声道) ~ 10000(右声道) 之间. 超出无效.
get_audio_balance() :                                    获取声道参数, 返回值在 –10000(左声道) ~ 10000(右声道) 之间.
set_audio_volume(volume) :                         设定音量.  volume 在 0 ~ 10000 之间.
get_audio_volume() :                                    获取音量. 返回值在 0 ~ 10000 之间.
set_play_rate(rate) :                                     设定播放效率. rate 为 2 就是2倍播放. 不过不是所有的格式视频都支持播放. 理论上 rate 为负值的话, 可以实现倒播. 不过需要视频解码库的支持.
set_start_stop_position(startPos, stopPos) : 设置视频起始位置. 两个参数以 毫秒 未单位.
set_current_position(pos) :                           设置当前播放位置(毫秒)
get_current_position() :                                获取当前播放位置(毫秒)
get_time_lenght() :                                       获取视频长度(毫秒)
set_layer_rect() :                                          设置播放矩形. 两种调用格式, set_layer_rect(layerNumber, rect) 和 set_layer_rect(layerNumber, x, y, width, height).
get_z_order(layerNumber, zOrder):             设置 Z 值. layerNumber 视频播放层数 .zOrder Z 值
get_z_order(layerNumber):                          获取 Z 值, layerNumber 视频播放层数.
get_alpha(layerNumber) :                            获取透明度, layerNumber 视频播放层数.
set_alpha(layerNumber, alpha):                    设置透明度, layerNumber 视频播放层数, alpha 透明度.
dispose_video():                                          释放
get_last_error():                                          获取最后一次错误的信息.
load_video_file(videoFileName, layerNumber): 加载视频文件. 参数同 Scene_Video .
play():                                                         播放
stop():                                                        暂停 / 停止
reset():                                                        重置
update():                                                    画面更新. 一般无需调用该方法.
over?():                                                      是否播放结束

测试环境
OS: Window XP SP3(x86)
DirectX : 9.0C
  1. #===============================================================================
  2. # ■ [VX]RM VX 视频播放插件
  3. #    [VX]RMVXVideo <- 没有空格、下划线
  4. #-------------------------------------------------------------------------------
  5. #    使用说明:
  6. #
  7. #    * 请先确定您所使用的视频文件格式, 具体的可以查看文件的扩展名.
  8. #
  9. #    * 确认后, 请打开"引用网址", 从中下载文件格式的解码器. 都下载也是可以的,
  10. #    不过这样工程会比较臃肿.
  11. #
  12. #    * 解压解码库, 将里面的全部 dll 文件都添加到 VideoData 文件夹下. 注意:
  13. #    VideoData 文件夹下只能放置 dll 文件.
  14. #
  15. #    * 最后可以使用脚本了. 脚本使用方法如下:
  16. #       $scene = Scene_Video.new(file_name, layer, x, y, width, height, type, playing, play_mode)
  17. #         其中:
  18. #         file_name(String)         : 文件名
  19. #         layer(int)                : 加载层数
  20. #         x, y, width. height(int)  : 播放画布范围定义.
  21. #         type(int)                 : 返回类型 0 Scene_Title; 1 Scene_Map
  22. #         playing(bool)             : 播放开始类型 true 立即播放; false 手动播放
  23. #         play_mode(bool)           : 播放模式 true 独占模式; false 异步模式  
  24. #
  25. #    * 独占模式: 视频在播放的时候让 RM 处于暂停状态, 除非视频播放结束, 或者玩家
  26. #    提前按下 B 键后, 场景才会切换回定义的场景. 玩家按下 C 键的话, 视频会暂停,
  27. #    再次按下继续播放
  28. #
  29. #    * 异步模式: 视频开始播放后, 立即切换到定义的返回场景. 这样就可以一边播放视
  30. #    频, 一边继续 RM 游戏. 不过注意会掉点FPS. 不过对视频毫无影响. 使用这个模式的
  31. #    话, 需要使用者自己手动切换视频的状态(播放, 暂停什么的), 播放结束后也需要使
  32. #    用者自己释放资源
  33. #
  34. #    * 状态方法的使用说明:
  35. #    参见"引用网址"
  36. #-------------------------------------------------------------------------------
  37. #    更新作者: 蕾米莉亚·斯卡雷特 or 铃仙·优昙华院·因幡
  38. #    许可协议: FSL-DNB-DNR-MEE
  39. #    引用网址: http://rpg.blue/thread-162230-1-1.html
  40. #-------------------------------------------------------------------------------
  41. #    - beta  By 蕾米莉亚·斯卡雷特 or 铃仙·优昙华院·因幡
  42. #      * 基本脚本 和 dll 组建
  43. #
  44. #    - 1.0.1127  By 蕾米莉亚·斯卡雷特 or 铃仙·优昙华院·因幡
  45. #      * 使用新架构来构建
  46. #
  47. #    - 2.0.0418  By 蕾米莉亚·斯卡雷特 or 铃仙·优昙华院·因幡
  48. #      * 不定期更新一些编码库
  49. #      * 新的编码库调用方案,减少对系统环境的依赖
  50. #
  51. #    - 3.0.0420  By 蕾米莉亚·斯卡雷特 or 铃仙·优昙华院·因幡
  52. #      * 新的窗口使用方案. 可以融合进 RM 里
  53. #      * 添加异步模式和独占模式选择.
  54. #
  55. #===============================================================================
复制代码

VideoData_MP4.rar

580.28 KB, 下载次数: 0

video.rar

1.41 MB, 下载次数: 0

东方神灵庙.mp4

5.26 MB, 下载次数: 0


作者: 高须小龙    时间: 2010-11-27 14:56
沙发,前排支持。
作者: ~屎猴子~    时间: 2010-11-27 14:57
喵、、
下载中、、
作者: yujiaye123    时间: 2010-11-28 11:39
哈哈~~~谢谢分享啦~~~
作者: clande    时间: 2010-11-28 15:21
XX出品,必属精品!。。= =!:lol
作者: 小角色    时间: 2010-11-28 16:31
测试者过来挤前排
作者: 迷路子    时间: 2010-11-28 19:09
全屏时影片播放会有问题
有声音但无影像
作者: zh99998    时间: 2010-11-28 19:40
回复 迷路子 的帖子

目前的解码器是智能链接, 但是并不代表所有的视频格式都可以使用, 常见格式的添加要看看这个脚本的使用人数. 使用的人少了, 更新也是浪费时间~~
作者: 巧克力猫咪    时间: 2010-11-29 14:55
晕,我郁闷,我能播放,中途退出也行,结束里竟然跳出 ,这是电脑 的问题还是游戏的问题啊,汗,郁闷死了
作者: 精灵使者    时间: 2010-11-29 14:59
回头测试一下下恩……
顺便与我原来的那个播放器做个比较。
作者: qiji19980124    时间: 2010-12-5 20:11
话说我看到了LZ的反白
作者: 鬼教师MK3    时间: 2010-12-9 07:14
楼主辛苦 跪拜!!

作者: 光的圆周率    时间: 2010-12-17 15:24
zz出品,必属精品
作者: 沉影不器    时间: 2010-12-21 20:19
提示: 作者被禁止或删除 内容自动屏蔽
作者: 八云紫    时间: 2010-12-21 22:58
底层是 DirectX , 所以需要 DirectX9.0c 的支持的说. c++ 运行库可能也需要吧. 这个没测试过~~
作者: summer92    时间: 2010-12-22 10:45
播放完视频,就报错 game.exe遇到问题需要关闭 什么情况?....关闭的时候有问题?
作者: 八云紫    时间: 2010-12-22 11:29
请您确认下是否安装完整的 DirectX9.0 . 不过没去理解 DirectX10.0 和 9.0 有啥不一样的地方.

可能需要 C++ 运行库的支持.

最后是, 咱的开发平台是 Win XP ,其他的系统不敢保证能不能使用. 不过 X64 的一般无法使用.
作者: 神行天下    时间: 2011-1-23 00:22
播放和中途退出都没有问题,不过播放完说是内存不能读为READ,能不能解决下
作者: MC毒舌    时间: 2011-2-4 20:41
哇靠,太强大了,谢谢楼主分享
作者: mirumo1234    时间: 2011-3-26 22:25
我播放的时候出现这个问题
出现c:\\Documetns and settings\\administrator\????\RM\vedioRM\\vedioRM.cpp,line 250XXXXXXXX\265\275\266
我默认的视频文件不在C盘,我想修改其路径为安装盘的路径(安装盘会变化)请问下如何在哪里修改?
请作者回复
谢谢
作者: zh99998    时间: 2011-3-27 06:58
回复 mirumo1234 的帖子

使用相对路径即可
作者: Front    时间: 2011-4-1 18:39
能让视频播放后继续游戏吗?怎么视频播放后就直接跳出游戏了....麻烦楼主解释~
作者: zh99998    时间: 2011-4-2 13:48
回复 Front 的帖子

请看脚本注释,有个参数可以控制播放完后回到哪
作者: Front    时间: 2011-4-2 20:50
回复 zh99998 的帖子

$scene = Scene_Video.new("Mo/Med.avi", 1, 1) 我输入是这样,但是播放结束后他就整个带我穿越到了桌面..
作者: zh99998    时间: 2011-4-3 19:10
回复 Front 的帖子

调用的那里 最后加一句p RmVideoPlayer.get_last_error,看看具体什么错误
另外方便的话,整个工程也发上来吧

作者: mirumo1234    时间: 2011-4-8 18:42
好吧
我也是播放到最后就出错了!!
那么我就把游戏工程简易版
给你吧。。
很大!
麻烦你一定要修复这个问题啊
http://u.115.com/file/f673c00b5f#
Project1.exe
作者: zh99998    时间: 2011-4-17 21:32
2011-4-17更新
还发现有什么bug的话,请回复或PM我,谢谢
作者: JJF    时间: 2011-4-17 21:39
本帖最后由 JJF 于 2011-4-17 22:22 编辑

更新了,顶一下
但后两个附件下载不了,给个115吧

作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-17 22:32
组件包: f432de2bd0
MP4解码库: f4fb0c59a8
作者: yangff    时间: 2011-4-17 22:54
顶LZ,终于更新了
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-17 23:12
回复 yangff 的帖子

现在的问题不是在于拦截 RM 自身的更新方法.

问题在于就算是拦截掉了, RM 不再刷新画面了, 但是脚本的图像描绘部分也会跟着直接瘫痪. 不能描绘图像什么的额, 就算是拦截掉了, 和现在这样不调用 update 有啥区别么?
作者: 天使怪盗    时间: 2011-4-18 00:39
zh喵好厉害~~
作者: zh99998    时间: 2011-4-18 10:12
蕾米莉亚·斯卡雷特 发表于 2011-4-17 22:32
组件包: f432de2bd0
MP4解码库: f4fb0c59a8

thx, 主楼已更新
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-18 12:20
本帖最后由 蕾米莉亚·斯卡雷特 于 2011-4-18 13:53 编辑

更新 rmvb 解码库:

VideoData(RMVB).rar (1.72 MB, 下载次数: 4155)

115:
f43cf4c528
作者: yangff    时间: 2011-4-18 18:23
蕾米莉亚·斯卡雷特 发表于 2011-4-17 23:12
回复 yangff 的帖子

现在的问题不是在于拦截 RM 自身的更新方法.

汗……我的意思是这样的

  DxStartDraw
  DxDraw
  在这里插入视屏的描绘
  DxEndDraw

  
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-18 18:28
回复 yangff 的帖子

默认视频不需要刷新.

一刷新就算不调用 update 也会闪屏~
作者: yangff    时间: 2011-4-18 19:52
蕾米莉亚·斯卡雷特 发表于 2011-4-18 18:28
回复 yangff 的帖子

默认视频不需要刷新.

什么叫不要刷新?你用的是多线程?那就更简单了,把描绘的目标附加到子窗体上,然后给GAME.EXE加一个WS_CLIPCHILDREN,但是这样有可能会掉FPS(WS_CLIPCHILDREN的作用是屏蔽被子窗体遮住部分的描绘工作,对RM有效)
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-18 20:51
回复 yangff 的帖子

那个, 测试了一下. 原理上就不可以的话.

开始播放视频之前就把视频播放窗口附加进 RM 的窗口里. 所以, 修改WS_CLIPCHILDREN 无效. 因为是同一个窗口.
作者: yangff    时间: 2011-4-18 21:32
本帖最后由 yangff 于 2011-4-18 21:36 编辑
蕾米莉亚·斯卡雷特 发表于 2011-4-18 20:51
回复 yangff 的帖子

那个, 测试了一下. 原理上就不可以的话.


我是这么做的……
父窗体是这样创建的

        DWORD dwStyle = (WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE | WS_CLIPCHILDREN);

        hWnd = ::CreateWindowEx(WS_EX_WINDOWEDGE, pWndClassName, szTitle, dwStyle,
                rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top, 0, 0, hInstance, 0);
子窗体
module APIs
  def self.make_window(x,y,width,height) #return hwnd
    #p $hInstance
    CWE.call(WS::EX_WINDOWEDGE,'RGSS Player','CWebB',WS::CHILD|WS::VISIBLE,x,y,width,height,get_hWnd,0,$hInstance,0)
    #CreateWindowEx.call(1, "Edit", "", W, 0, 0, w, h, GetActiveWindow.call, 1, GetModuleHandle.call(nil), 1)
  end
end
这样的话子窗体所在区域是不会描绘的
然后调用相关dll的时候直接把make_window返回的句柄传进去……
主要的作用还是嵌入视屏……不过因该比较卡……如果背景在动画的话……至少Flash如此……
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-18 21:37
那啥, 我的做法是直接在 RM 的窗口上描绘刷新的话, 没有创建子窗口.

不过使用子窗口来覆盖掉原 RM 窗口的话, 也是不错的.

不过要拦截掉 RM 窗口的移动消息, WM_MOVE. 有点麻烦就是~~~
作者: yangff    时间: 2011-4-19 12:42
蕾米莉亚·斯卡雷特 发表于 2011-4-18 21:37
那啥, 我的做法是直接在 RM 的窗口上描绘刷新的话, 没有创建子窗口.

不过使用子窗口来覆盖掉原 RM 窗口的 ...

不用啊……子窗体的位置就是相对父窗体的吧……
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-19 14:56
回复 yangff 的帖子

都说了, 现在的做法没有子窗口~~
作者: yangff    时间: 2011-4-19 16:05
蕾米莉亚·斯卡雷特 发表于 2011-4-19 14:56
回复 yangff 的帖子

都说了, 现在的做法没有子窗口~~

我的意思是这样……
诡异的vx……视屏居然1桢都没掉……Flash你敢不敢别这么蛋疼……
video_full.rar (1.43 MB, 下载次数: 914)
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-19 16:39
本帖最后由 蕾米莉亚·斯卡雷特 于 2011-4-19 16:48 编辑

回复 yangff 的帖子

居然可以? = =
求原理~~~

定制 Game.exe 可不行~~~

-----------------------------------

了解了, 创建窗口什么的. 恩, 咱试试整合一下~~~
作者: yangff    时间: 2011-4-19 18:47
蕾米莉亚·斯卡雷特 发表于 2011-4-19 16:39
回复 yangff 的帖子

居然可以? = =

  1. #==============================================================================
  2. # ■ Kernel
  3. #------------------------------------------------------------------------------
  4. #  该模块中定义了可供所有类使用的方法。Object 类中包含了该模块。
  5. #==============================================================================

  6. module Kernel
  7.   #--------------------------------------------------------------------------
  8.   # ● 需要的 Windows API 函数
  9.   #--------------------------------------------------------------------------
  10.   #没有定制的Game的话……
  11. GetWindowLong=Win32API.new('User32','GetWindowLongA','ll','l')
  12. SetWindowLong= Win32API.new('User32','SetWindowLongA','lll','l')
  13. GetWindowThreadProcessId = Win32API.new("user32", "GetWindowThreadProcessId", "LP", "L")
  14.   GetWindow = Win32API.new("user32", "GetWindow", "LL", "L")
  15.   GetClassName = Win32API.new("user32", "GetClassName", "LPL", "L")
  16.   GetCurrentThreadId = Win32API.new("kernel32", "GetCurrentThreadId", "V", "L")
  17.   GetForegroundWindow = Win32API.new("user32", "GetForegroundWindow", "V", "L")#CreateWindowEx(
  18.   $hInstance=Win32API.new("Kernel32","GetModuleHandleA","","l").call()
  19. #DWORD dwExStyle,LPCTSTR IpClassName,
  20. #LPCTSTR lpWindowName,DWORD dwStyle,
  21. #int x,int y,int nWidth,int nHeight,
  22. #HWND hWndParent,HMENU hMenu,
  23. #HANDLE hInstance,LPVOID lpParam);
  24.   module WS
  25.     EX_MDICHILD=0x40
  26.     EX_WINDOWEDGE=0x100
  27.     #CHILD=0x40000000
  28.     #VISIBLE=0x10000000
  29.      OVERLAPPED      = 0x00000000
  30. POPUP          =  0x80000000
  31. CHILD          =  0x40000000
  32. MINIMIZE       =  0x20000000
  33. VISIBLE        =  0x10000000
  34. DISABLED        = 0x08000000
  35. CLIPSIBLINGS    = 0x04000000
  36. CLIPCHILDREN    = 0x02000000
  37. MAXIMIZE        = 0x01000000
  38. CAPTION         = 0x00C00000   
  39. BORDER          = 0x00800000
  40. DLGFRAME        = 0x00400000
  41. VSCROLL         = 0x00200000
  42. HSCROLL         = 0x00100000
  43. SYSMENU         = 0x00080000
  44. THICKFRAME      = 0x00040000
  45. GROUP           = 0x00020000
  46. TABSTOP         = 0x00010000
  47. MINIMIZEBOX    = 0x00020000
  48.   end
  49.   @hh=0
  50.   CWE = Win32API.new('user32','CreateWindowEx','lppllllllllp','l')
  51.   def self.make_window(x,y,width,height) #return hwnd
  52.     #p $hInstance
  53.     CWE.call(WS::EX_WINDOWEDGE,'RGSS Player','CWebB',WS::CHILD|WS::VISIBLE,x,y,width,height,get_hWnd,0,$hInstance,0)
  54.     #CreateWindowEx.call(1, "Edit", "", W, 0, 0, w, h, GetActiveWindow.call, 1, GetModuleHandle.call(nil), 1)
  55.   end

  56.   #--------------------------------------------------------------------------
  57.   # ● 获取窗口句柄
  58.   #--------------------------------------------------------------------------
  59.   def self.get_hWnd
  60.     return @hh if @hh!=0
  61.     # 获取调用线程(RM 的主线程)的进程标识
  62.     threadID = GetCurrentThreadId.call
  63.     # 获取 Z 次序中最靠前的窗口
  64.     hWnd = GetWindow.call(GetForegroundWindow.call, 0)
  65.     # 枚举所有窗口
  66.     while hWnd != 0
  67.       # 如果创建该窗口的线程标识匹配本线程标识
  68.       if threadID == GetWindowThreadProcessId.call(hWnd, 0)
  69.         # 分配一个 11 个字节的缓冲区
  70.         className = " " * 11
  71.         # 获取该窗口的类名
  72.         GetClassName.call(hWnd, className, 12)
  73.         # 如果匹配 RGSS Player 则跳出循环
  74.         break if className == "RGSS Player"
  75.       end
  76.       # 获取下一个窗口
  77.       hWnd = GetWindow.call(hWnd, 2)
  78.     end
  79.     return @hh=hWnd
  80.   end
  81. end
  82. os=GetWindowLong.call(Kernel.get_hWnd,-16)
  83. SetWindowLong.call(Kernel.get_hWnd,-16,os | 33554432)
复制代码
那就这样……
作者: zh99998    时间: 2011-4-20 13:57
4-20更新
v3.0.0420 视频与RM画面共存
作者: 亿万星辰    时间: 2011-4-20 16:47
这个更新好,我可以继续更新下我签名里的东西……
作者: link006007    时间: 2011-4-21 20:11
恩  好东西  。。 好久没来
作者: yangff    时间: 2011-4-21 21:58
本帖最后由 yangff 于 2011-4-21 21:58 编辑
zh99998 发表于 2010-11-27 14:47
独占模式:


异步什么的开个线程自动释放吧……再加个Proc什么的……
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-21 22:06
异步的写法感觉是给会写点点脚本的人准备的. 个人感觉.

Ruby 的多线程有点感觉.......

不过, Ruby 多线程怎么写?  忘记了.

咱等下更新下好了.
作者: 一箭烂YiJL    时间: 2011-4-21 22:58
回复 蕾米莉亚·斯卡雷特 的帖子

这样?Thread.new{loop{影片.update;sleep(1/Graphics.frame_rate)}}

于是有关详细Ruby的线程(Thread)的操作送上:
http://www.kuqin.com/rubycndocum ... _object_thread.html

实际上我还真没试过这个RM播放器呢~
还有就是Flash不是必须安装FlashPlayer的吗?
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-21 23:13
回复 一箭烂YiJL 的帖子

不是必须的, 安装了 FlashXX.ocx 的 ActiveX 控件就可以了~~
作者: killkill2298    时间: 2011-4-22 00:21
全屏播放AVI闪屏,播放范例的却正常,不知道是何原因
作者: 爱丽丝·玛格特罗依德    时间: 2011-4-22 11:25
回复 killkill2298 的帖子

目前脚本是使用自动链接到合适的解码链的, 但是自动的代价就是不是最优的.

而且 AVI 的编码很多. 所以请查看一下您所使用的 AVI视频 的编码格式, 方便的话请告诉我(最好是有这个格式的视频文件给我), 我帮你找一下合适的解码库~~
作者: killkill2298    时间: 2011-4-22 15:15
本帖最后由 killkill2298 于 2011-4-22 15:22 编辑

在WMP中查看信息:

视频长度 03:53
比特率 - (估计无法识别)
音频解码器:- (我这视频本来就没声音)
视频解码器: MPEG Video Decoder

是在这里看么?
作者: yangff    时间: 2011-4-22 17:43
蕾米莉亚·斯卡雷特 发表于 2011-4-21 23:13
回复 一箭烂YiJL 的帖子

不是必须的, 安装了 FlashXX.ocx 的 ActiveX 控件就可以了~~ ...

话说视屏是怎么显示的?DD?解码器返回的是什么?是Bitmap矩阵么?如果是的话可以考虑用61的那个获取Bitmap内存地址的方法把视屏嵌到Bitmap里面,这样就不会挡住别的东西了……
解码什么的不是很熟&……
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-22 20:23
回复 yangff 的帖子

核心是 DirectShow , 解码链 返回的是 IPin 接口。 显示啥的, 是框架问题。 不是 Bitmap 就是了。
作者: yangff    时间: 2011-4-22 20:38
本帖最后由 yangff 于 2011-4-22 20:40 编辑
蕾米莉亚·斯卡雷特 发表于 2011-4-22 20:23
回复 yangff 的帖子

核心是 DirectShow , 解码链 返回的是 IPin 接口。 显示啥的, 是框架问题。 不是 Bi ...


DS 貌似可以导出Bitmap矩阵的
GetCurrentBuffer(size,buff)
一段有关的代码……欢迎蛋疼……表示没装Dx/Platform SDK= =
能成的话就用Mp4做真战斗背景神马的了-= = |||
  1. //////////////////////////////////////////////////////////////////////
  2. // Video Capture using DirectShow
  3. // Author: Shiqi Yu ([email protected])
  4. // Thanks to:
  5. //                HardyAI@OpenCV China
  6. //                flymanbox@OpenCV China (for his contribution to function CameraName, and frame width/height setting)
  7. // Last modification: April 9, 2009
  8. //////////////////////////////////////////////////////////////////////


  9. //////////////////////////////////////////////////////////////////////
  10. // 使用说明:
  11. //   1. 将CameraDS.h CameraDS.cpp以及目录DirectShow复制到你的项目中
  12. //   2. 菜单 Project->Settings->Settings for:(All configurations)->C/C++->Category(Preprocessor)->Additional include directories
  13. //      设置为 DirectShow/Include
  14. //   3. 菜单 Project->Settings->Settings for:(All configurations)->Link->Category(Input)->Additional library directories
  15. //      设置为 DirectShow/Lib
  16. //////////////////////////////////////////////////////////////////////

  17. // CameraDS.cpp: implementation of the CCameraDS class.
  18. //
  19. //////////////////////////////////////////////////////////////////////

  20. #include "CameraDS.h"

  21. #pragma comment(lib,"Strmiids.lib")
  22. //////////////////////////////////////////////////////////////////////
  23. // Construction/Destruction
  24. //////////////////////////////////////////////////////////////////////

  25. CCameraDS::CCameraDS()
  26. {
  27.         m_bConnected = m_bLock = m_bChanged = false;
  28.         m_nWidth = m_nHeight = 0;
  29.         m_nBufferSize = 0;

  30.         m_pFrame = NULL;

  31.         m_pNullFilter = NULL;
  32.         m_pMediaEvent = NULL;
  33.         m_pSampleGrabberFilter = NULL;
  34.         m_pGraph = NULL;

  35.         CoInitialize(NULL);
  36. }

  37. CCameraDS::~CCameraDS()
  38. {
  39.         CloseCamera();
  40.         CoUninitialize();
  41. }

  42. void CCameraDS::CloseCamera()
  43. {
  44.         if(m_bConnected)
  45.         {
  46.                 m_pMediaControl->Stop();
  47.         }

  48.         m_pGraph = NULL;
  49.         m_pDeviceFilter = NULL;
  50.         m_pMediaControl = NULL;
  51.         m_pSampleGrabberFilter = NULL;
  52.         m_pSampleGrabber = NULL;
  53.         m_pGrabberInput = NULL;
  54.         m_pGrabberOutput = NULL;
  55.         m_pCameraOutput = NULL;
  56.         m_pMediaEvent = NULL;
  57.         m_pNullFilter = NULL;
  58.         m_pNullInputPin = NULL;

  59.         if (m_pFrame)
  60.         {
  61.                 cvReleaseImage(&m_pFrame);
  62.         }

  63.         m_bConnected = m_bLock = m_bChanged = false;
  64.         m_nWidth = m_nHeight = 0;
  65.         m_nBufferSize = 0;
  66. }

  67. bool CCameraDS::OpenCamera(int nCamID, bool bDisplayProperties, int nWidth, int nHeight)
  68. {
  69.         HRESULT hr = S_OK;

  70.         CoInitialize(NULL);
  71.         // Create the Filter Graph Manager.
  72.         hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGraph);

  73.         hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID *)&m_pSampleGrabberFilter);

  74.         hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **) &m_pMediaControl);
  75.         hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **) &m_pMediaEvent);

  76.         hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (LPVOID*) &m_pNullFilter);

  77.         hr = m_pGraph->AddFilter(m_pNullFilter, L"NullRenderer");

  78.         hr = m_pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber, (void**)&m_pSampleGrabber);

  79.         AM_MEDIA_TYPE   mt;
  80.         ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
  81.         mt.majortype = MEDIATYPE_Video;
  82.         mt.subtype = MEDIASUBTYPE_RGB24;
  83.         mt.formattype = FORMAT_VideoInfo;
  84.         hr = m_pSampleGrabber->SetMediaType(&mt);
  85.         MYFREEMEDIATYPE(mt);

  86.         m_pGraph->AddFilter(m_pSampleGrabberFilter, L"Grabber");

  87.         // Bind Device Filter.  We know the device because the id was passed in
  88.         BindFilter(nCamID, &m_pDeviceFilter);
  89.         m_pGraph->AddFilter(m_pDeviceFilter, NULL);

  90.         CComPtr<IEnumPins> pEnum;
  91.         m_pDeviceFilter->EnumPins(&pEnum);

  92.         hr = pEnum->Reset();
  93.         hr = pEnum->Next(1, &m_pCameraOutput, NULL);

  94.         pEnum = NULL;
  95.         m_pSampleGrabberFilter->EnumPins(&pEnum);
  96.         pEnum->Reset();
  97.         hr = pEnum->Next(1, &m_pGrabberInput, NULL);

  98.         pEnum = NULL;
  99.         m_pSampleGrabberFilter->EnumPins(&pEnum);
  100.         pEnum->Reset();
  101.         pEnum->Skip(1);
  102.         hr = pEnum->Next(1, &m_pGrabberOutput, NULL);

  103.         pEnum = NULL;
  104.         m_pNullFilter->EnumPins(&pEnum);
  105.         pEnum->Reset();
  106.         hr = pEnum->Next(1, &m_pNullInputPin, NULL);

  107.         //SetCrossBar();

  108.         if (bDisplayProperties)
  109.         {
  110.                 CComPtr<ISpecifyPropertyPages> pPages;

  111.                 HRESULT hr = m_pCameraOutput->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pPages);
  112.                 if (SUCCEEDED(hr))
  113.                 {
  114.                         PIN_INFO PinInfo;
  115.                         m_pCameraOutput->QueryPinInfo(&PinInfo);

  116.                         CAUUID caGUID;
  117.                         pPages->GetPages(&caGUID);

  118.                         OleCreatePropertyFrame(NULL, 0, 0,
  119.                                                 L"Property Sheet", 1,
  120.                                                 (IUnknown **)&(m_pCameraOutput.p),
  121.                                                 caGUID.cElems, caGUID.pElems,
  122.                                                 0, 0, NULL);

  123.                         CoTaskMemFree(caGUID.pElems);
  124.                         PinInfo.pFilter->Release();
  125.                 }
  126.                 pPages = NULL;
  127.         }
  128.         else
  129.         {
  130.                 //////////////////////////////////////////////////////////////////////////////
  131.                 // 加入由 lWidth和lHeight设置的摄像头的宽和高 的功能,默认320*240
  132.                 // by flymanbox @2009-01-24
  133.                 //////////////////////////////////////////////////////////////////////////////
  134.                 IAMStreamConfig *iconfig = NULL;
  135.                 hr = m_pCameraOutput->QueryInterface(IID_IAMStreamConfig, (void**)&iconfig);   

  136.                 AM_MEDIA_TYPE *pmt;
  137.                 if(iconfig->GetFormat(&pmt) !=S_OK)
  138.                 {
  139.                         //printf("GetFormat Failed ! \n");
  140.                         return false;
  141.                 }

  142.                 // 3、考虑如果此时的的图像大小正好是 nWidth * nHeight,则就不用修改了。
  143.                 if ((pmt->lSampleSize != (nWidth * nHeight * 3)) && (pmt->formattype == FORMAT_VideoInfo))
  144.                 {
  145.                         VIDEOINFOHEADER *phead = (VIDEOINFOHEADER*)(pmt->pbFormat);
  146.                         phead->bmiHeader.biWidth = nWidth;
  147.                         phead->bmiHeader.biHeight = nHeight;
  148.                         if((hr = iconfig->SetFormat(pmt)) != S_OK)
  149.                         {
  150.                                 return false;
  151.                         }
  152.                 }

  153.                 iconfig->Release();
  154.                 iconfig=NULL;
  155.                 MYFREEMEDIATYPE(*pmt);
  156.         }

  157.         hr = m_pGraph->Connect(m_pCameraOutput, m_pGrabberInput);
  158.         hr = m_pGraph->Connect(m_pGrabberOutput, m_pNullInputPin);

  159.         if (FAILED(hr))
  160.         {
  161.                 switch(hr)
  162.                 {
  163.                         case VFW_S_NOPREVIEWPIN :
  164.                                 break;
  165.                         case E_FAIL :
  166.                                 break;
  167.                         case E_INVALIDARG :
  168.                                 break;
  169.                         case E_POINTER :
  170.                                 break;
  171.                 }
  172.         }

  173.         m_pSampleGrabber->SetBufferSamples(TRUE);
  174.         m_pSampleGrabber->SetOneShot(TRUE);
  175.    
  176.         hr = m_pSampleGrabber->GetConnectedMediaType(&mt);
  177.         if(FAILED(hr))
  178.         {
  179.                 return false;
  180.         }

  181.         VIDEOINFOHEADER *videoHeader;
  182.         videoHeader = reinterpret_cast<VIDEOINFOHEADER*>(mt.pbFormat);
  183.         m_nWidth = videoHeader->bmiHeader.biWidth;
  184.         m_nHeight = videoHeader->bmiHeader.biHeight;
  185.         m_bConnected = true;

  186.         pEnum = NULL;
  187.         return true;
  188. }


  189. bool CCameraDS::BindFilter(int nCamID, IBaseFilter **pFilter)
  190. {
  191.         if (nCamID < 0)
  192.         {
  193.                 return false;
  194.         }

  195.     // enumerate all video capture devices
  196.         CComPtr<ICreateDevEnum> pCreateDevEnum;
  197.         HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);
  198.         if (hr != NOERROR)
  199.         {
  200.                 return false;
  201.         }

  202.     CComPtr<IEnumMoniker> pEm;
  203.     hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
  204.     if (hr != NOERROR)
  205.         {
  206.                 return false;
  207.     }

  208.     pEm->Reset();
  209.     ULONG cFetched;
  210.     IMoniker *pM;
  211.         int index = 0;
  212.     while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= nCamID)
  213.     {
  214.                 IPropertyBag *pBag;
  215.                 hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
  216.                 if(SUCCEEDED(hr))
  217.                 {
  218.                         VARIANT var;
  219.                         var.vt = VT_BSTR;
  220.                         hr = pBag->Read(L"FriendlyName", &var, NULL);
  221.                         if (hr == NOERROR)
  222.                         {
  223.                                 if (index == nCamID)
  224.                                 {
  225.                                         pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);
  226.                                 }
  227.                                 SysFreeString(var.bstrVal);
  228.                         }
  229.                         pBag->Release();
  230.                 }
  231.                 pM->Release();
  232.                 index++;
  233.     }

  234.         pCreateDevEnum = NULL;
  235.         return true;
  236. }

  237. //将输入crossbar变成PhysConn_Video_Composite
  238. void CCameraDS::SetCrossBar()
  239. {
  240.         int i;
  241.         IAMCrossbar *pXBar1 = NULL;
  242.         ICaptureGraphBuilder2 *pBuilder = NULL;

  243.         HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&pBuilder);

  244.         if (SUCCEEDED(hr))
  245.         {
  246.                 hr = pBuilder->SetFiltergraph(m_pGraph);
  247.         }

  248.         hr = pBuilder->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, m_pDeviceFilter,IID_IAMCrossbar, (void**)&pXBar1);

  249.         if (SUCCEEDED(hr))
  250.         {
  251.                   long OutputPinCount, InputPinCount;
  252.                 long PinIndexRelated, PhysicalType;
  253.                 long inPort = 0, outPort = 0;

  254.                 pXBar1->get_PinCounts(&OutputPinCount, &InputPinCount);
  255.                 for( i =0;i<InputPinCount;i++)
  256.                 {
  257.                         pXBar1->get_CrossbarPinInfo(TRUE,i,&PinIndexRelated,&PhysicalType);
  258.                         if(PhysConn_Video_Composite==PhysicalType)
  259.                         {
  260.                                 inPort = i;
  261.                                 break;
  262.                         }
  263.                 }
  264.                 for( i =0;i<OutputPinCount;i++)
  265.                 {
  266.                         pXBar1->get_CrossbarPinInfo(FALSE,i,&PinIndexRelated,&PhysicalType);
  267.                         if(PhysConn_Video_VideoDecoder==PhysicalType)
  268.                         {
  269.                                 outPort = i;
  270.                                 break;
  271.                         }
  272.                 }
  273.   
  274.                 if(S_OK==pXBar1->CanRoute(outPort,inPort))
  275.                 {
  276.                         pXBar1->Route(outPort,inPort);
  277.                 }
  278.                 pXBar1->Release();  
  279.         }
  280.         pBuilder->Release();
  281. }

  282. /*
  283. The returned image can not be released.
  284. */
  285. IplImage* CCameraDS::QueryFrame()
  286. {
  287.         long evCode, size = 0;

  288.         m_pMediaControl->Run();
  289.         m_pMediaEvent->WaitForCompletion(INFINITE, &evCode);

  290.         m_pSampleGrabber->GetCurrentBuffer(&size, NULL);

  291.         //if the buffer size changed
  292.         if (size != m_nBufferSize)
  293.         {
  294.                 if (m_pFrame)
  295.                 {
  296.                         cvReleaseImage(&m_pFrame);
  297.                 }

  298.                 m_nBufferSize = size;
  299.                 m_pFrame = cvCreateImage(cvSize(m_nWidth, m_nHeight), IPL_DEPTH_8U, 3);
  300.         }

  301.         m_pSampleGrabber->GetCurrentBuffer(&m_nBufferSize, (long*)m_pFrame->imageData);
  302.         cvFlip(m_pFrame);

  303.         return m_pFrame;
  304. }

  305. int CCameraDS::CameraCount()
  306. {
  307.         int count = 0;
  308.         CoInitialize(NULL);

  309.    // enumerate all video capture devices
  310.         CComPtr<ICreateDevEnum> pCreateDevEnum;
  311.     HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);

  312.     CComPtr<IEnumMoniker> pEm;
  313.     hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
  314.     if (hr != NOERROR)
  315.         {
  316.                 return count;
  317.     }

  318.     pEm->Reset();
  319.     ULONG cFetched;
  320.     IMoniker *pM;
  321.     while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
  322.     {
  323.                 count++;
  324.     }

  325.         pCreateDevEnum = NULL;
  326.         pEm = NULL;
  327.         return count;
  328. }

  329. int CCameraDS::CameraName(int nCamID, char* sName, int nBufferSize)
  330. {
  331.         int count = 0;
  332.         CoInitialize(NULL);

  333.    // enumerate all video capture devices
  334.         CComPtr<ICreateDevEnum> pCreateDevEnum;
  335.     HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum);

  336.     CComPtr<IEnumMoniker> pEm;
  337.     hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEm, 0);
  338.     if (hr != NOERROR) return 0;

  339.     pEm->Reset();
  340.     ULONG cFetched;
  341.     IMoniker *pM;
  342.     while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
  343.     {
  344.                 if (count == nCamID)
  345.                 {
  346.                         IPropertyBag *pBag=0;
  347.                         hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
  348.                         if(SUCCEEDED(hr))
  349.                         {
  350.                                 VARIANT var;
  351.                                 var.vt = VT_BSTR;
  352.                                 hr = pBag->Read(L"FriendlyName", &var, NULL); //还有其他属性,像描述信息等等...
  353.                     if(hr == NOERROR)
  354.                         {
  355.                                 //获取设备名称                       
  356.                                         WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1,sName, nBufferSize ,"",NULL);

  357.                         SysFreeString(var.bstrVal);                               
  358.                         }
  359.                             pBag->Release();
  360.                         }
  361.                         pM->Release();

  362.                         break;
  363.                 }
  364.                 count++;
  365.     }

  366.         pCreateDevEnum = NULL;
  367.         pEm = NULL;

  368.         return 1;
  369. }
复制代码
  1. //////////////////////////////////////////////////////////////////////
  2. // Video Capture using DirectShow
  3. // Author: Shiqi Yu ([email protected])
  4. // Thanks to:
  5. //                HardyAI@OpenCV China
  6. //                flymanbox@OpenCV China (for his contribution to function CameraName, and frame width/height setting)
  7. // Last modification: April 9, 2009
  8. //
  9. // 使用说明:
  10. //   1. 将CameraDS.h CameraDS.cpp以及目录DirectShow复制到你的项目中
  11. //   2. 菜单 Project->Settings->Settings for:(All configurations)->C/C++->Category(Preprocessor)->Additional include directories
  12. //      设置为 DirectShow/Include
  13. //   3. 菜单 Project->Settings->Settings for:(All configurations)->Link->Category(Input)->Additional library directories
  14. //      设置为 DirectShow/Lib
  15. //////////////////////////////////////////////////////////////////////

  16. #ifndef CCAMERA_H
  17. #define CCAMERA_H

  18. #define WIN32_LEAN_AND_MEAN

  19. #include <atlbase.h>

  20. #include "qedit.h"
  21. #include "dshow.h"

  22. #include <windows.h>
  23. #include <cxcore.h>

  24. #define MYFREEMEDIATYPE(mt)        {if ((mt).cbFormat != 0)                \
  25.                                         {CoTaskMemFree((PVOID)(mt).pbFormat);        \
  26.                                         (mt).cbFormat = 0;                                                \
  27.                                         (mt).pbFormat = NULL;                                        \
  28.                                 }                                                                                        \
  29.                                 if ((mt).pUnk != NULL)                                                \
  30.                                 {                                                                                        \
  31.                                         (mt).pUnk->Release();                                        \
  32.                                         (mt).pUnk = NULL;                                                \
  33.                                 }}                                                                       

  34. class CCameraDS  
  35. {
  36. private:

  37.         bool m_bConnected, m_bLock, m_bChanged;

  38.         int m_nWidth, m_nHeight;

  39.         long m_nBufferSize;

  40.         IplImage *m_pFrame;

  41.         CComPtr<IGraphBuilder> m_pGraph;

  42.         CComPtr<ISampleGrabber> m_pSampleGrabber;

  43.         CComPtr<IMediaControl> m_pMediaControl;

  44.         CComPtr<IMediaEvent> m_pMediaEvent;

  45.         CComPtr<IBaseFilter> m_pSampleGrabberFilter;
  46.         CComPtr<IBaseFilter> m_pDeviceFilter;
  47.         CComPtr<IBaseFilter> m_pNullFilter;

  48.         CComPtr<IPin> m_pGrabberInput;
  49.         CComPtr<IPin> m_pGrabberOutput;
  50.         CComPtr<IPin> m_pCameraOutput;
  51.         CComPtr<IPin> m_pNullInputPin;

  52.         bool BindFilter(int nCamIDX, IBaseFilter **pFilter);

  53.         void SetCrossBar();

  54. public:

  55.         CCameraDS();
  56.         virtual ~CCameraDS();

  57.         //打开摄像头,nCamID指定打开哪个摄像头,取值可以为0,1,2,...
  58.         //bDisplayProperties指示是否自动弹出摄像头属性页
  59.         //nWidth和nHeight设置的摄像头的宽和高,如果摄像头不支持所设定的宽度和高度,则返回false
  60.         bool OpenCamera(int nCamID, bool bDisplayProperties = true, int nWidth = 320, int nHeight = 240);

  61.         //关闭摄像头,析构函数会自动调用这个函数
  62.         void CloseCamera();

  63.         //返回摄像头的数目
  64.         //可以不用创建CCameraDS实例,采用int c=CCameraDS::CameraCount();得到结果。
  65.         static int CameraCount();

  66.         //根据摄像头的编号返回摄像头的名字
  67.         //nCamID: 摄像头编号
  68.         //sName: 用于存放摄像头名字的数组
  69.         //nBufferSize: sName的大小
  70.         //可以不用创建CCameraDS实例,采用CCameraDS::CameraName();得到结果。
  71.         static int CameraName(int nCamID, char* sName, int nBufferSize);

  72.         //返回图像宽度
  73.         int GetWidth(){return m_nWidth;}

  74.         //返回图像高度
  75.         int GetHeight(){return m_nHeight;}

  76.         //抓取一帧,返回的IplImage不可手动释放!
  77.         //返回图像数据的为RGB模式的Top-down(第一个字节为左上角像素),即IplImage::origin=0(IPL_ORIGIN_TL)
  78.         IplImage * QueryFrame();
  79. };

  80. #endif
复制代码

作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-22 20:48
回复 yangff 的帖子

GetCurrentBuffer

截图什么的功能打算在 3.1 3.2 的时候添加。 不过每帧都截图是不是太那个啊。 而且要想真的和 Rm 合体什么的, 有点难度。

不过目前最大的问题还是 解码链路 还是自动连接,对系统的要求比较大就是了。 手动连接就好多了。 不过要求很高。

对于返回的那个 内存图片 的内存结构会不会还没研究过。 (大概是一样的)

作者: yangff    时间: 2011-4-22 21:20
本帖最后由 yangff 于 2011-4-22 21:22 编辑
蕾米莉亚·斯卡雷特 发表于 2011-4-22 20:48
回复 yangff 的帖子

GetCurrentBuffer


这种方法的FPS在30左右时无压力的……不知道60会不会……大不了跳帧= =反正有几个视屏的FPS到60了= =
但是据说CPU各种吃没试过= =这个导的是摄像头的

这段代码本来是用来把DS的那一坨转成Ocv的那一坨……
显然这种玩意返回的东西可以在RM里面直接用
Rm的Bitmap是BGRA的Top-down=int
这个返回的是BGR模式的Top-down
到时候怎么位移一下就好了= =
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-22 21:38
回复 yangff 的帖子

少了个 A 感觉少了好多。

视频 Filter 都是可以截图的。 摄像头本来想添加进去, 不过想想这个貌似用处不大。 开着 RM 视频聊天么? = =

总感觉每帧截图再转换再加载再显示, 效率能达到 10FPS 就不错了。 这样可使每帧 Blt 啊。
作者: yangff    时间: 2011-4-22 21:49
蕾米莉亚·斯卡雷特 发表于 2011-4-22 21:38
回复 yangff 的帖子

少了个 A 感觉少了好多。

不会,扫一遍不会影响FPS的= =虽然是Blt但是直接搞内存还是很快的 = =
GetCurrentBuffer不知道支不支持A通道= =但是Dx的话因该是可以的吧
至于解码……我觉得弄个FFmpge什么的就差不多了吧,Kmp用的也就是FF啊
不过GPL很讨厌就是了
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-22 22:37
回复 yangff 的帖子

解码链 都是会找可以使用的, 基本上算是最优的组合方法。

A 通道什么的, DX 不应该不支持才对。 这个问题不大。 主要是 blt 的效率问题 。

Bitmap 先 new 的话, 也应该在内存里才对吧。

而且视频最少需要 24FPS 才流畅。 估计效率上很麻烦。

解码库什么的, 有空有需求了再说。万能解码库啥的,还没遇见过。

QQPlayer 还不算是万能的。 它的解码库是用 dll 堆起来的。 = =
作者: yangff    时间: 2011-4-22 22:45
本帖最后由 yangff 于 2011-4-22 22:49 编辑
蕾米莉亚·斯卡雷特 发表于 2011-4-22 22:37
回复 yangff 的帖子

解码链 都是会找可以使用的, 基本上算是最优的组合方法。


啥……反正我是记得FFmpge可以解几乎所有的……当然现在这么多乱七八糟的也不好说,但是至少常用的没问题的说……
Bitmap我的意思是这样的
class Video < Bitmap
  def address

    buffer, ad = "xxxx", object_id * 2 + 16

    RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0] + 8

    RtlMoveMemory_pi.call(buffer, ad, 4); ad = buffer.unpack("L")[0] + 16

    RtlMoveMemory_pi.call(buffer, ad, 4); return buffer.unpack("L")[0]

  end
  def initialize(url)
    @handle,w,h=GetRect.call(url).unpack("L*")
    super(w,h)
    SetAddr(@handle,address)
  end
  def update
    if (FPS)
      MovieUpdate.call(@handle)
    end
  end
  def dispose
    MovieDispose.call(@handle)
  end
end
效率不用担心,我写过一个斜切的,每桢PIA一个新的Bitmap然后用新的度数切一遍再XXXXXX再修改透明度,FPS在50无压力只是加一个A更无压力了肯定……我担心的是Dx但效率反而(d7说他能到60我才不信……)
只不过我对RM统计的FPS各种怀疑不需要原因的那种
作者: 炎影者    时间: 2011-4-23 13:11
这个要支持!!
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-23 15:46
回复 yangff 的帖子

那咱去试试看. FPS 掉不多的话还好~~~
作者: ssjr    时间: 2011-4-24 00:40
为什么我用同样的格式视频不能播放视频,只能听到声音,用默认的那个却很正常?
作者: 蕾米莉亚·斯卡雷特    时间: 2011-4-24 13:42
回复 ssjr 的帖子

就算是同一种格式的视频也有区分不同的编码格式.

LS 可以的话, 告诉咱视频编码, 咱去找找对应的解码库. 直接给视频也是可以的. ~~~
作者: 一箭烂YiJL    时间: 2011-4-24 13:50
回复 蕾米莉亚·斯卡雷特 的帖子

发布区合并了,高难度的VX视频和XP视频播放器都同在一起了= =
我"提高游戏运行速度"两个都在一起了= =
不过我那个VX能用XP的,XP不能用VX的= =
我都不知怎么处理- -。
作者: ssjr    时间: 2011-4-24 19:51
回复 蕾米莉亚·斯卡雷特 的帖子

就是以前那个视频版本,我放了AVI的视频替换之前的视频 却无法正常播放画面出来,只能听到声音!我怎么把视频文件传给你啊?
作者: 铃仙·优昙华院·因幡    时间: 2011-4-24 20:08
回复 ssjr 的帖子

传 115 给个提取码也可以.

传 QQ中转站, 发邮件到 [email protected] 也可以(请注明内容啥的,好区分.)

或者告诉咱视频编码格式什么的. 这个用软件来查看.
作者: ssjr    时间: 2011-4-24 20:19
回复 铃仙·优昙华院·因幡 的帖子

好的 谢谢 这是提取码!t144c08b53
作者: 铃仙·优昙华院·因幡    时间: 2011-4-24 21:17
回复 ssjr 的帖子

那啥, FMP4 视频编码的还真没遇到过. 找不到比较好的解码器.

可以的话, 就转格式吧, MP4 什么的, 都可以, 转换的时候注意选择 视频编码格式为 "AVC"

这个就可以使用之前上传的那个 MP4 解码器了~~
作者: ssjr    时间: 2011-4-24 22:16
回复 铃仙·优昙华院·因幡 的帖子

恩 好的谢谢你啊,我下了个编码转换器,转成AVC用试试,呵呵!~


ssjr于2011-4-26 01:11补充以下内容:
饿,我转码成功了 呵呵!但是还有个问题需要解决,就是视频自动播放完成后总是弹出错误提示,中途跳过播放,就不会出错,这个问题怎么解决啊?


ssjr于2011-4-27 18:23补充以下内容:
如何解决播放完后出错?


ssjr于2011-4-27 21:33补充以下内容:
饿,我转码成功了 呵呵!但是还有个问题需要解决,就是视频自动播放完成后总是弹出错误提示,中途跳过播放,就不会出错,这个问题怎么解决啊
作者: [email protected]    时间: 2011-6-14 21:06
  好
作者: 反斗奇彬    时间: 2011-6-17 18:51
好久没见过这么好的东西了,可惜共享已经到期了
作者: SOU    时间: 2011-7-2 10:50
那个,我想问一下。如果我想把视频文件放在\Graphics\Video 文件夹下,应该做些什么?
m(_ _)m
作者: 素材发布    时间: 2011-7-28 11:52
为什么我播放的事显示不了呐
作者: feishzz    时间: 2011-8-9 10:20
本帖最后由 feishzz 于 2011-8-9 10:25 编辑


我这样写对卜对啊?
应该不对吧···
还有视频应该放在哪个文件夹里面啊???
LZ怎么都不说啊

发生这个情况···
作者: 315038639    时间: 2011-8-9 14:52
我也遇到了和楼上同样的问题,不知道是哪出错了。
我把四页脚本都粘贴了过来,把那个VideoData文件夹也复制了过来。
事件中运行的脚本是 $scene = Scene_Video.new("东方神灵庙.mp4", 1, 0, 0, 544, 416, 0, true, true)
那个视频复制到了和Game.exe同目录下

(楼上的是3 for 9,我的是9 for 3)


315038639于2011-8-9 14:57补充以下内容:
我也是和楼上相同的问题
我把4页脚本复制过来,然后把那个VD文件夹也复制了过来,把Video.dll也复制了,那个视频也原封不动地复制了过来
在事件中运行:$scene = Scene_Video.new("东方神灵庙", 1, 0, 0, 544, 416, 0, true, true)
然后出现下面的状况
[attachimg]69692[/attachimg]
求教咋办?
作者: 1370528656    时间: 2012-2-9 18:36
XP党表示遗憾。这么好的脚本用不了。期待有人转XP。
作者: ddr2012    时间: 2012-3-29 21:43
楼主,小弟这边有个问题,播放视频的时候没声音,有影像,不知怎么解决,用的是范例的视频【东方神灵庙.MP4】范例也是没声音的,郁闷
作者: シスコン    时间: 2012-5-5 11:18
给跪了……不能用……、
作者: mzr1996    时间: 2012-5-7 05:27
不知该说些什么。。。。。。就是谢谢
作者: kuerlulu    时间: 2012-8-5 10:59
avi可以支持么
作者: houyuxiaoyang    时间: 2012-8-6 20:42
用不了啊……RmVideoPlayer的第9行出现了Runtime Error Load Library:Video .dll
作者: 多余的流星    时间: 2012-8-11 22:51
干嘛不加个快进功能,可以前进几百帧
作者: 1587937102    时间: 2012-11-9 21:14
注意视频的分辨率。
作者: dota1100    时间: 2012-12-3 10:05
下载不了呀……各位大大们……
作者: dota1100    时间: 2012-12-3 10:24
大部分附件均已处于无法读取阶段,无法下载……唉……
作者: hongxiaoyu    时间: 2013-3-21 17:45
~屎猴子~ 发表于 2010-11-27 14:57
喵、、
下载中、、

哭瞎了.><
菊苣还有这个脚本么?
已经下载不下来了..><
作者: hongxiaoyu    时间: 2013-3-21 17:46
哭瞎了.><
菊苣还有这个脚本么?
已经下载不下来了..><
作者: 卡奥尼特    时间: 2013-8-30 21:58
我晕,本来想找一个RM播放器,却发现附件无法读取0.0
作者: 289307768    时间: 2014-1-11 16:36
这东西太好使了,感激不尽!收下了!




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1