上周完成了一个屏幕录制节目,实时屏幕捕获、记录,视频H.264压缩,音频应用AAC压缩,复用MP4格公式,这使得计算机和ios设备上直接播放。支持HTML5的播放器都能够放,这是标准格式的优点。抓屏也添加了自己主动缩放的功能,參考我的上一篇博客。把这几部分的思路都整理一下。

抓屏,方法非常多,直接用bitblt、使用directx、使用mirrordriver、甚至还实用mediaencoder的,我比較了bitblt和directx的方法,也查了非常多资料。

直觉的理解应该是directx的速度会快一些,可是其实因为win7系统对bitblt进行了处理。速度与directx抓屏不相上下。代码也简洁非常多非常多,几行代码就解决,在我的thinkpad T410每秒轻轻松松抓屏100多帧。CPU占用也不高。在有些显卡比較差的机器上。性能会急剧下降,可是这样的情况下directx也好不到哪去。单纯从抓屏来说。用bitblt足够了。mediaencoder就算了,太麻烦,还得安装一堆东西。mirrordriver没去细致看。似乎是用这个驱动能够从镜像里面直接获得变化的屏幕数据。这和我的需求不同。我是须要抓整屏。而不是仅仅要变化的部分。假设不是抓屏,而是做屏幕的远程控制,那能够參考vnc、TightVNC、ReallVNC这些开源的代码,都做得相当好。机制不同。我希望是用标准的格式去压缩整个屏幕的,这点VNC的小伙伴们採用的机制无法实现。

抓屏代码:

  1. BitBlt(hMemDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY);
  2. GetDIBits(hMemDC, bmp, 0, height, bmpBuffer, &bminfo, DIB_RGB_COLORS);

抓屏以后,RGB32位的数据要转换为YUV,这个代码假设直接用浮点运算实现,那效率相当低。我用的是xvid里面的一段汇编代码,使用了MMX指令。速度非常快。

大家能够去參考xvid的代码。话说xvid好几年没更新代码,近期又開始更新了。好奇怪。。。曾经做mpeg4的时候。感觉xvid太牛了。编码效率极高,如今被x264代替了。。。扯远了,看看RGB2YUV的代码:

;/**************************************************************************

  1. ; *
  2. ; * mmx colorspace conversions
  3. ; *
  4. ; *************************************************************************/
  5.  
  6. bits 32
  7.  
  8. section .data
  9.  
  10. %macro cglobal 1
  11. %ifdef PREFIX
  12. global _%1
  13. %define %1 _%1
  14. %else
  15. global %1
  16. %endif
  17. %endmacro
  18.  
  19. align 16
  20.  
  21. ;===========================================================================
  22. ; yuv constants
  23. ;===========================================================================
  24.  
  25. %define Y_R 0.257
  26. %define Y_G 0.504
  27. %define Y_B 0.098
  28. %define Y_ADD 16
  29.  
  30. %define U_R 0.148
  31. %define U_G 0.291
  32. %define U_B 0.439
  33. %define U_ADD 128
  34.  
  35. %define V_R 0.439
  36. %define V_G 0.368
  37. %define V_B 0.071
  38. %define V_ADD 128
  39.  
  40. ;===========================================================================
  41. ; multiplication matrices
  42. ;===========================================================================
  43.  
  44. ; %define SCALEBITS 8
  45.  
  46. y_mul dw 25 ; FIX(Y_B)
  47. dw 129 ; FIX(Y_G)
  48. dw 66 ; FIX(Y_R)
  49. dw 0
  50.  
  51. u_mul dw 112 ; FIX(U_B)
  52. dw -74 ; FIX(U_G)
  53. dw -38 ; FIX(U_R)
  54. dw 0
  55.  
  56. v_mul dw -18 ; FIX(V_B)
  57. dw -94 ; FIX(V_G)
  58. dw 112 ; FIX(V_R)
  59. dw 0
  60.  
  61. section .text
  62.  
  63. ;===========================================================================
  64. ;
  65. ; void rgb24_to_yv12_mmx(uint8_t * const y_out,
  66. ; uint8_t * const u_out,
  67. ; uint8_t * const v_out,
  68. ; const uint8_t * const src,
  69. ; const uint32_t width,
  70. ; const uint32_t height,
  71. ; const uint32_t stride)
  72. ;
  73. ; always flips
  74. ;
  75. ;===========================================================================
  76.  
  77. align 16
  78. cglobal rgb24_to_yv12_mmx
  79. rgb24_to_yv12_mmx
  80.  
  81. push ebx
  82. push ecx
  83. push esi
  84. push edi
  85. push ebp ; STACK BASE = 20
  86.  
  87. ; global consants
  88.  
  89. mov eax, [esp + 20 + 28] ; stride
  90. mov ecx, [esp + 20 + 20] ; width
  91. mov ebx, eax
  92. sub ebx, ecx
  93. shr ebx, 1 ; ebx = (stride-width) / 2;
  94. push ebx ; [esp + 20] = uv_dif
  95. ; STACK BASE = 24
  96.  
  97. add eax, eax
  98. sub eax, ecx ; eax = 2*stride - width
  99. push eax ; [esp + 16] = y_dif
  100. ; STACK BASE = 28
  101.  
  102. mov ebx, ecx ;
  103. shr ebx, 1 ;
  104. push ebx ; [esp + 12] = width/2
  105. ; STACK BASE = 32
  106.  
  107. mov edx, ecx
  108. add ecx, edx
  109. add ecx, edx ; ecx = 3*width (use 4 for rgb32)
  110. push ecx ; [esp + 8] = width3
  111. ; STACK BASE = 36
  112.  
  113. mov edx, ecx
  114. add edx, ecx
  115. add edx, ecx ; edx = 3*width3
  116. push edx ; [esp + 4] = src_dif
  117. ; STACK BASE = 40
  118.  
  119. mov esi, [esp + 40 + 16] ; src
  120. mov ebp, [esp + 40 + 24] ; eax = height
  121. mov eax, ebp
  122. sub eax, 2
  123. mul ecx
  124. add esi, eax ; src += (height-2) * width3
  125.  
  126. mov edi, [esp + 40 + 4] ; y_out
  127. mov ecx, [esp + 40 + 8] ; u_out
  128. mov edx, [esp + 40 + 12] ; v_out
  129. movq mm7, [y_mul]
  130.  
  131. shr ebp, 1 ; ebp = height / 2
  132. push ebp ; [esp+0] = tmp
  133. ; STACK BASE = 44
  134.  
  135. .yloop
  136. mov ebp, [esp + 12] ; ebp = width /2
  137.  
  138. .xloop
  139. ; y_out
  140.  
  141. mov ebx, [esp + 8] ; ebx = width3
  142.  
  143. pxor mm4, mm4
  144. pxor mm5, mm5
  145. movd mm0, [esi] ; src[0...]
  146. movd mm2, [esi+ebx] ; src[width3...]
  147. punpcklbw mm0, mm4 ; [ |b |g |r ]
  148. punpcklbw mm2, mm5 ; [ |b |g |r ]
  149. movq mm6, mm0 ; = [ |b4|g4|r4]
  150. paddw mm6, mm2 ; +[ |b4|g4|r4]
  151. pmaddwd mm0, mm7 ; *= Y_MUL
  152. pmaddwd mm2, mm7 ; *= Y_MUL
  153. movq mm4, mm0 ; [r]
  154. movq mm5, mm2 ; [r]
  155. psrlq mm4, 32 ; +[g]
  156. psrlq mm5, 32 ; +[g]
  157. paddd mm0, mm4 ; +[b]
  158. paddd mm2, mm5 ; +[b]
  159.  
  160. pxor mm4, mm4
  161. pxor mm5, mm5
  162. movd mm1, [esi+3] ; src[4...]
  163. movd mm3, [esi+ebx+3] ; src[width3+4...]
  164. punpcklbw mm1, mm4 ; [ |b |g |r ]
  165. punpcklbw mm3, mm5 ; [ |b |g |r ]
  166. paddw mm6, mm1 ; +[ |b4|g4|r4]
  167. paddw mm6, mm3 ; +[ |b4|g4|r4]
  168. pmaddwd mm1, mm7 ; *= Y_MUL
  169. pmaddwd mm3, mm7 ; *= Y_MUL
  170. movq mm4, mm1 ; [r]
  171. movq mm5, mm3 ; [r]
  172. psrlq mm4, 32 ; +[g]
  173. psrlq mm5, 32 ; +[g]
  174. paddd mm1, mm4 ; +[b]
  175. paddd mm3, mm5 ; +[b]
  176.  
  177. mov ebx, [esp + 44 + 28] ; stride
  178.  
  179. movd eax, mm0
  180. shr eax, 8
  181. add eax, Y_ADD
  182. mov [edi + ebx], al
  183.  
  184. movd eax, mm1
  185. shr eax, 8
  186. add eax, Y_ADD
  187. mov [edi + ebx + 1], al
  188.  
  189. movd eax, mm2
  190. shr eax, 8
  191. add eax, Y_ADD
  192. mov [edi], al
  193.  
  194. movd eax, mm3
  195. shr eax, 8
  196. add eax, Y_ADD
  197. mov [edi + 1], al
  198.  
  199. ; u_out, v_out
  200.  
  201. movq mm0, mm6 ; = [ |b4|g4|r4]
  202. pmaddwd mm6, [v_mul] ; *= V_MUL
  203. pmaddwd mm0, [u_mul] ; *= U_MUL
  204. movq mm1, mm0
  205. movq mm2, mm6
  206. psrlq mm1, 32
  207. psrlq mm2, 32
  208. paddd mm0, mm1
  209. paddd mm2, mm6
  210.  
  211. movd eax, mm0
  212. shr eax, 10
  213. add eax, U_ADD
  214. mov [ecx], al
  215.  
  216. movd eax, mm2
  217. shr eax, 10
  218. add eax, V_ADD
  219. mov [edx], al
  220.  
  221. add esi, 2 * 3 ; (use 4 for rgb32)
  222. add edi, 2
  223. inc ecx
  224. inc edx
  225.  
  226. dec ebp
  227. jnz near .xloop
  228.  
  229. sub esi, [esp + 4] ; src -= src_dif
  230. add edi, [esp + 16] ; y_out += y_dif
  231. add ecx, [esp + 20] ; u_out += uv_dif
  232. add edx, [esp + 20] ; v_out += uv_dif
  233.  
  234. dec dword [esp+0]
  235. jnz near .yloop
  236.  
  237. emms
  238.  
  239. add esp, 24
  240. pop ebp
  241. pop edi
  242. pop esi
  243. pop ecx
  244. pop ebx
  245.  
  246. ret
  247.  
  248. ;===========================================================================
  249. ;
  250. ; void rgb32_to_yv12mmx(uint8_t * const y_out,
  251. ; uint8_t * const u_out,
  252. ; uint8_t * const v_out,
  253. ; const uint8_t * const src,
  254. ; const uint32_t width,
  255. ; const uint32_t height,
  256. ; const uint32_t stride)
  257. ;
  258. ; always flips
  259. ;
  260. ;===========================================================================
  261.  
  262. align 16
  263. cglobal rgb32_to_yv12_mmx
  264. rgb32_to_yv12_mmx
  265.  
  266. push ebx
  267. push ecx
  268. push esi
  269. push edi
  270. push ebp ; STACK BASE = 20
  271.  
  272. ; global consants
  273.  
  274. mov eax, [esp + 20 + 28] ; stride
  275. mov ecx, [esp + 20 + 20] ; width
  276. mov ebx, eax
  277. sub ebx, ecx
  278. shr ebx, 1 ; ebx = (stride-width) / 2;
  279. push ebx ; [esp + 20] = uv_dif
  280. ; STACK BASE = 24
  281.  
  282. add eax, eax
  283. sub eax, ecx ; eax = 2*stride - width
  284. push eax ; [esp + 16] = y_dif
  285. ; STACK BASE = 28
  286.  
  287. mov ebx, ecx ;
  288. shr ebx, 1 ;
  289. push ebx ; [esp + 12] = width/2
  290. ; STACK BASE = 32
  291.  
  292. mov edx, ecx
  293. shl ecx, 2 ; ecx = 4*width (use 4 for rgb32)
  294. push ecx ; [esp + 8] = width4
  295. ; STACK BASE = 36
  296.  
  297. mov edx, ecx
  298. add edx, ecx
  299. add edx, ecx ; edx = 3*width4
  300. push edx ; [esp + 4] = src_dif
  301. ; STACK BASE = 40
  302.  
  303. mov esi, [esp + 40 + 16] ; src
  304. mov ebp, [esp + 40 + 24] ; eax = height
  305. mov eax, ebp
  306. sub eax, 2
  307. mul ecx
  308. add esi, eax ; src += (height-2) * width4
  309.  
  310. mov edi, [esp + 40 + 4] ; y_out
  311. mov ecx, [esp + 40 + 8] ; u_out
  312. mov edx, [esp + 40 + 12] ; v_out
  313. movq mm7, [y_mul]
  314.  
  315. shr ebp, 1 ; ebp = height / 2
  316. push ebp ; [esp+0] = tmp
  317. ; STACK BASE = 44
  318.  
  319. .yloop
  320. mov ebp, [esp + 12] ; ebp = width /2
  321.  
  322. .xloop
  323. ; y_out
  324.  
  325. mov ebx, [esp + 8] ; ebx = width4
  326.  
  327. pxor mm4, mm4
  328. movq mm0, [esi] ; src[4... |0... ]
  329. movq mm2, [esi+ebx] ; src[width4+4...|width4...]
  330. movq mm1, mm0
  331. movq mm3, mm2
  332. punpcklbw mm0, mm4 ; [ |b |g |r ]
  333. punpcklbw mm2, mm4 ; [ |b |g |r ]
  334. punpckhbw mm1, mm4 ; [ |b |g |r ]
  335. punpckhbw mm3, mm4 ; [ |b |g |r ]
  336.  
  337. movq mm6, mm0 ; = [ |b4|g4|r4]
  338. paddw mm6, mm2 ; +[ |b4|g4|r4]
  339. pmaddwd mm0, mm7 ; *= Y_MUL
  340. pmaddwd mm2, mm7 ; *= Y_MUL
  341. movq mm4, mm0 ; [r]
  342. movq mm5, mm2 ; [r]
  343. psrlq mm4, 32 ; +[g]
  344. psrlq mm5, 32 ; +[g]
  345. paddd mm0, mm4 ; +[b]
  346. paddd mm2, mm5 ; +[b]
  347.  
  348. paddw mm6, mm1 ; +[ |b4|g4|r4]
  349. paddw mm6, mm3 ; +[ |b4|g4|r4]
  350. pmaddwd mm1, mm7 ; *= Y_MUL
  351. pmaddwd mm3, mm7 ; *= Y_MUL
  352. movq mm4, mm1 ; [r]
  353. movq mm5, mm3 ; [r]
  354. psrlq mm4, 32 ; +[g]
  355. psrlq mm5, 32 ; +[g]
  356. paddd mm1, mm4 ; +[b]
  357. paddd mm3, mm5 ; +[b]
  358.  
  359. mov ebx, [esp + 44 + 28] ; stride
  360.  
  361. movd eax, mm0
  362. shr eax, 8
  363. add eax, Y_ADD
  364. mov [edi + ebx], al
  365.  
  366. movd eax, mm1
  367. shr eax, 8
  368. add eax, Y_ADD
  369. mov [edi + ebx + 1], al
  370.  
  371. movd eax, mm2
  372. shr eax, 8
  373. add eax, Y_ADD
  374. mov [edi], al
  375.  
  376. movd eax, mm3
  377. shr eax, 8
  378. add eax, Y_ADD
  379. mov [edi + 1], al
  380.  
  381. ; u_out, v_out
  382.  
  383. movq mm0, mm6 ; = [ |b4|g4|r4]
  384. pmaddwd mm6, [v_mul] ; *= V_MUL
  385. pmaddwd mm0, [u_mul] ; *= U_MUL
  386. movq mm1, mm0
  387. movq mm2, mm6
  388. psrlq mm1, 32
  389. psrlq mm2, 32
  390. paddd mm0, mm1
  391. paddd mm2, mm6
  392.  
  393. movd eax, mm0
  394. shr eax, 10
  395. add eax, U_ADD
  396. mov [ecx], al
  397.  
  398. movd eax, mm2
  399. shr eax, 10
  400. add eax, V_ADD
  401. mov [edx], al
  402.  
  403. add esi, 2 * 4 ; (use 4 for rgb32)
  404. add edi, 2
  405. inc ecx
  406. inc edx
  407.  
  408. dec ebp
  409. jnz near .xloop
  410.  
  411. sub esi, [esp + 4] ; src -= src_dif
  412. add edi, [esp + 16] ; y_out += y_dif
  413. add ecx, [esp + 20] ; u_out += uv_dif
  414. add edx, [esp + 20] ; v_out += uv_dif
  415.  
  416. dec dword [esp+0]
  417. jnz near .yloop
  418.  
  419. emms
  420.  
  421. add esp, 24
  422. pop ebp
  423. pop edi
  424. pop esi
  425. pop ecx
  426. pop ebx
  427.  
  428. ret

转换为YUV数据以后。就是压缩了。用H.264,基本上都是x264了。开源的代码,如今速度也挺快。交叉编译生成DLL直接调用即可。这里參数设置非常重要,帧率我做的是每分钟1帧到25x60帧可调,注意是每分钟不是秒。x264大家都非常熟悉,不多说了。

音频部分比較简单了,设定採样率,用acm採集,然后aac压缩。

AAC也有开源的LibFAAC代码能够使用。

264文件和AAC文件生成以后,复用的方法有非常多,简单起见,能够用ffmpeg或其它的软件进行复用。注意别让ffmpeg进行二次编码压缩,否则速度慢并且质量损失。

完毕的程序,測了一下。1920x1980的分辨率,自己主动缩放为1280x720,每秒1帧,录制10分钟的mp4文件大概是4M多。画面清晰,声音清晰,达到预期目标了。接下来的工作是实时直播了。考虑到兼容性和流媒体的特点。使用rtmp协议,而没实用rtsp。

用rtmp的长处就是接收端用flash能够播放,不须要安装其它插件了。

rtmp协议是不开放的,可是也难不倒我们,librtmp是开源的,做的非常好。可是移植到windows平台编译还是费了一些周折。

要注意的几点:

1、在c/c++预处理器加上NO_CRYPTO。不编ssl部分,不须要加密

2、rtmp.c文件中面。凝视掉几行代码

  1. //#ifdef _DEBUG
  2. //extern FILE *netstackdump;
  3. //extern FILE *netstackdump_read;
  4. //#endif
  5. //#ifdef _DEBUG
  6. // fwrite(ptr, 1, nBytes, netstackdump_read);
  7. //#endif
  8. //#ifdef _DEBUG
  9. // fwrite(buf, 1, len, netstackdump);
  10. //#endif

3、编译时须要链接ws2_32.lib库

编译以后,生成dll。在主程序里面调用。主要的初始化代码:

  1. /*分配与初始化*/
  2. rtmp = RTMP_Alloc();
  3. RTMP_Init(rtmp);
  4.  
  5. /*设置URL*/
  6. if (RTMP_SetupURL(rtmp,rtmp_url) == FALSE) {
  7. log(LOG_ERR,"RTMP_SetupURL() failed!");
  8. RTMP_Free(rtmp);
  9. return -1;
  10. }
  11.  
  12. /*设置可写,即公布流,这个函数必须在连接前使用,否则无效*/
  13. RTMP_EnableWrite(rtmp);
  14.  
  15. /*连接server*/
  16. if (RTMP_Connect(rtmp, NULL) == FALSE) {
  17. log(LOG_ERR,"RTMP_Connect() failed!");
  18. RTMP_Free(rtmp);
  19. return -1;
  20. }
  21.  
  22. /*连接流*/
  23. if (RTMP_ConnectStream(rtmp,0) == FALSE) {
  24. log(LOG_ERR,"RTMP_ConnectStream() failed!");
  25. RTMP_Close(rtmp);
  26. RTMP_Free(rtmp);
  27. return -1;
  28. }

然后在x264_encocer_encode编码一帧以后。调用rtmp的函数进行发送。

  1. size = x264_encoder_encode(cx->hd,&nal,&n,pic,&pout);
  2.  
  3. int i,last;
  4. for (i = 0,last = 0;i < n;i++) {
  5. if (nal[i].i_type == NAL_SPS) {
  6.  
  7. sps_len = nal[i].i_payload-4;
  8. memcpy(sps,nal[i].p_payload+4,sps_len);
  9.  
  10. } else if (nal[i].i_type == NAL_PPS) {
  11.  
  12. pps_len = nal[i].i_payload-4;
  13. memcpy(pps,nal[i].p_payload+4,pps_len);
  14.  
  15. /*发送sps pps*/
  16. send_video_sps_pps();
  17.  
  18. } else {
  19.  
  20. /*发送普通帧(剩下所有)*/
  21. send_rtmp_video(nal[i].p_payload,size-last)
  22. break;
  23. }
  24. last += nal[i].i_payload;
  25. }

发送的代码就不贴了。就是填充rtmp packet的内容。调试的时候发现创建socket失败,折腾半天最后发现是没有调用WSAStartup,低级错误。。

发送的数据流,用Flex air写了个接收程序。也有问题。air3.1能够正常接收。air3.9就不行。好吧。。。

今天继续看代码吧,找找原因。音频的发送程序类似,有空再加。

这个程序将会是我们即将公布的轻录播的一部分。这几天把其它代码完毕考虑把程序共享出来。

欢迎拍砖。

版权声明:本文博客原创文章。博客,未经同意,不得转载。

屏幕录制H.264视频,AAC音频,MP4复,LibRTMP现场活动的更多相关文章

  1. 视音频数据处理入门:H.264视频码流解析

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

  2. H.264 RTPpayload 格式------ H.264 视频 RTP 负载格式(包含AAC部分解析)

    H.264 RTPpayload 格式------ H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +------------ ...

  3. 工具---《.264视频 转成 MP4视频》

    <.264视频 转成 MP4视频> 安装了“爱奇艺万能播放器”可以打开.264视频,但是opencv却不能直接读取.264视频,还是需要想办法“.264视频 转成 MP4/avi视频”. ...

  4. 【转】实现RTP协议的H.264视频传输系统

    1.  引言       随着信息产业的发展,人们对信息资源的要求已经逐渐由文字和图片过渡到音频和视频,并越来越强调获取资源的实时性和互动性.但人们又面临着另外一种不可避免的尴尬,就是在网络上看到生动 ...

  5. H.264视频的RTP荷载格式

    Status of This Memo This document specifies an Internet standards track protocol for the   Internet ...

  6. H.264视频在android手机端的解码与播放(转)

    随着无线网络和智能手机的发展,智能手机与人们日常生活联系越来越紧密,娱乐.商务应用.金融应用.交通出行各种功能的软件大批涌现,使得人们的生活丰富多彩.快捷便利,也让它成为人们生活中不可取代的一部分.其 ...

  7. H.264 RTPpayload 格式------ H.264 视频 RTP 负载格式

    H.264 RTPpayload 格式------ H.264 视频 RTP 负载格式 1. 网络抽象层单元类型 (NALU) NALU 头由一个字节组成, 它的语法如下: +------------ ...

  8. H.264视频编解码SoC满足高清DVR设计需求

    硬盘录像机(DVR)作为监控系统的核心部件之一,在10年里高速发展,从模拟磁带机的替代品演变成具有自己独特价值的专业监控数字平台,并被市场广泛接受.监控系统伴随DVR这些年的发展向着IP化.智能化发展 ...

  9. ASP.NET MVC程序播放H.264视频

    在这篇之前,Insus.NET不管是在ASP.NET还是ASP.NET MVC实现很多视频播放,你可以参考这篇链接:http://www.cnblogs.com/insus/category/4650 ...

随机推荐

  1. DDD领域驱动设计仓储Repository

    DDD领域驱动设计初探(二):仓储Repository(上) 前言:上篇介绍了DDD设计Demo里面的聚合划分以及实体和聚合根的设计,这章继续来说说DDD里面最具争议的话题之一的仓储Repositor ...

  2. Shell编程入门(再版)(在)

    简单的演示样本Shell规划 演示样例1. #!/bin/bash #This is to show what a shell script looks like echo "Our fir ...

  3. Android使用HttpClient方法和易错问题

    HttpClient为Android开发人员提供了跟简洁的操作Http网络连接的方法,在连接过程中也有两种方式,get和post,先看一下怎样实现的 默认是get方式 //先将參数放入List,再对參 ...

  4. 使 IIS 6.0 可以在 64 位 Windows 上运行 32 位应用程序 试图加载格式不正确的程序。

    原文 使 IIS 6.0 可以在 64 位 Windows 上运行 32 位应用程序 试图加载格式不正确的程序. win7 64位操作系统上边运行IIS网站应用的时候,提示错误"试图加载格式 ...

  5. Java虚拟机类型卸载和类型更新解析(转)

    转自:http://www.blogjava.net/zhuxing/archive/2008/07/24/217285.html [摘要]          前面系统讨论过java 类型加载(loa ...

  6. javaEE异常摘要——更换工作区相同tomcat当部署在同一个项目疑难解答

    我有一个项目,我的工作区公告,没问题,它可以运行正常,但我把项目copy还有一个工作空间,然后发布到tomcat(随着tomcat,先前的工作空间remove deployment,公布信息)上去,想 ...

  7. Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Multiple representations of the same entity解决方法

    1.错误信息 Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUs ...

  8. CocoaPods停在Analyzing dependencies解决方案

    现在很多开源项目应用cocoapod.这使集成第三方库都非常方便,在没有花project里设置哪些参数.仗着. 只要运行pod update要么pod install时间,经常会卡在Analyzing ...

  9. 假设动态运行java文字,当在脚本式配置,这是非常方便的

    package com.bfrj.core.groovy; import java.util.HashMap; import java.util.Map; import org.jeecgframew ...

  10. 小记 js unicode 编码解析

    原文:小记 js unicode 编码解析 var str = "\\u6211\\u662Funicode\\u7F16\\u7801"; 关于这样的数据转换为中文问题,常用的两 ...