转自:http://blog.csdn.net/leixiaohua1020/article/details/39702113

版权声明:本文为博主原创文章,未经博主允许不得转载。

 
 

=====================================================
最简单的基于FFmpeg的AVDevice例子文章列表:

最简单的基于FFmpeg的AVDevice例子(读取摄像头)

最简单的基于FFmpeg的AVDevice例子(屏幕录制)
=====================================================

FFmpeg中有一个和多媒体设备交互的类库:Libavdevice。使用这个库可以读取电脑(或者其他设备上)的多媒体设备的数据,或者输出数据到指定的多媒体设备上。

Libavdevice支持以下设备作为输入端:

alsa
avfoundation
bktr
dshow
dv1394
fbdev
gdigrab
iec61883
jack
lavfi
libcdio
libdc1394
openal
oss
pulse
qtkit
sndio
video4linux2, v4l2
vfwcap
x11grab
decklink

Libavdevice支持以下设备作为输出端:

alsa
caca
decklink
fbdev
opengl
oss
pulse
sdl
sndio
xv

libavdevice使用

计划记录两个基于FFmpeg的libavdevice类库的例子,分成两篇文章写。本文记录一个基于FFmpeg的Libavdevice类库读取摄像头数据的例子。下一篇文章记录一个基于FFmpeg的Libavdevice类库录制屏幕的例子。本文程序读取计算机上的摄像头的数据并且解码显示出来。有关解码显示方面的代码本文不再详述,可以参考文章:
100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)

本文主要记录使用libavdevice需要注意的步骤。

首先,使用libavdevice的时候需要包含其头文件:

  1. #include "libavdevice/avdevice.h"

然后,在程序中需要注册libavdevice:

  1. avdevice_register_all();

接下来就可以使用libavdevice的功能了。
使用libavdevice读取数据和直接打开视频文件比较类似。因为系统的设备也被FFmpeg认为是一种输入的格式(即AVInputFormat)。使用FFmpeg打开一个普通的视频文件使用如下函数:

  1. AVFormatContext *pFormatCtx = avformat_alloc_context();
  2. avformat_open_input(&pFormatCtx, "test.h265",NULL,NULL);

使用libavdevice的时候,唯一的不同在于需要首先查找用于输入的设备。在这里使用av_find_input_format()完成:

  1. AVFormatContext *pFormatCtx = avformat_alloc_context();
  2. AVInputFormat *ifmt=av_find_input_format("vfwcap");
  3. avformat_open_input(&pFormatCtx, 0, ifmt,NULL);

上述代码首先指定了vfw设备作为输入设备,然后在URL中指定打开第0个设备(在我自己计算机上即是摄像头设备)。
在Windows平台上除了使用vfw设备作为输入设备之外,还可以使用DirectShow作为输入设备:

  1. AVFormatContext *pFormatCtx = avformat_alloc_context();
  2. AVInputFormat *ifmt=av_find_input_format("dshow");
  3. avformat_open_input(&pFormatCtx,"video=Integrated Camera",ifmt,NULL) ;

使用ffmpeg.exe打开vfw设备和Directshow设备的方法可以参考文章:
FFmpeg获取DirectShow设备数据(摄像头,录屏)

注意事项

1. URL的格式是"video={设备名称}",但是设备名称外面不能加引号。例如在上述例子中URL是"video=Integrated Camera",而不能写成"video=\"Integrated Camera\"",否则就无法打开设备。这与直接使用ffmpeg.exe打开dshow设备(命令为:ffmpeg -list_options true -f dshow -i video="Integrated Camera")有很大的不同。
2. Dshow的设备名称必须要提前获取,在这里有两种方法:

(1) 通过FFmpeg编程实现。使用如下代码:

  1. //Show Device
  2. void show_dshow_device(){
  3. AVFormatContext *pFormatCtx = avformat_alloc_context();
  4. AVDictionary* options = NULL;
  5. av_dict_set(&options,"list_devices","true",0);
  6. AVInputFormat *iformat = av_find_input_format("dshow");
  7. printf("Device Info=============\n");
  8. avformat_open_input(&pFormatCtx,"video=dummy",iformat,&options);
  9. printf("========================\n");
  10. }

上述代码实际上相当于输入了下面一条命令:

  1. ffmpeg -list_devices true -f dshow -i dummy

执行的结果如下图所示:

该方法好处是可以使用程序自动获取名称。但是当设备名称中包含中文字符的时候,会出现设备名称为乱码的情况。如果直接把乱码的设备名作为输入的话,是无法打开该设备的。这时候需要把乱码ANSI转换为UTF-8。例如上图中的第一个音频设备显示为“鍐呰楹﹀厠椋?(Conexant 20672 SmartAudi”,转码之后即为“内装麦克风 (Conexant 20672 SmartAudi”。使用转码之后的名称即可打开该设备。

(2) 自己去系统中看。
这个方法更简单一些,但是缺点是需要手工操作。该方法使用DirectShow的调试工具GraphEdit(或者网上下一个GraphStudioNext)即可查看输入名称。
打开GraphEdit选择“图像->插入滤镜”

 

然后就可以通过查看Audio Capture Sources来查看音频输入设备的简体中文名称了。从图中可以看出是“内装麦克风 (Conexant 20672 SmartAudi”。

 

在Linux平台上可以使用video4linux2打开视频设备;在MacOS上,可以使用avfoundation打开视频设备,这里不再详述。

代码

下面直接贴上程序代码:

  1. /**
  2. * 最简单的基于FFmpeg的AVDevice例子(读取摄像头)
  3. * Simplest FFmpeg Device (Read Camera)
  4. *
  5. * 雷霄骅 Lei Xiaohua
  6. * leixiaohua1020@126.com
  7. * 中国传媒大学/数字电视技术
  8. * Communication University of China / Digital TV Technology
  9. * http://blog.csdn.net/leixiaohua1020
  10. *
  11. * 本程序实现了本地摄像头数据的获取解码和显示。是基于FFmpeg
  12. * 的libavdevice类库最简单的例子。通过该例子,可以学习FFmpeg中
  13. * libavdevice类库的使用方法。
  14. * 本程序在Windows下可以使用2种方式读取摄像头数据:
  15. *  1.VFW: Video for Windows 屏幕捕捉设备。注意输入URL是设备的序号,
  16. *          从0至9。
  17. *  2.dshow: 使用Directshow。注意作者机器上的摄像头设备名称是
  18. *         “Integrated Camera”,使用的时候需要改成自己电脑上摄像头设
  19. *          备的名称。
  20. * 在Linux下可以使用video4linux2读取摄像头设备。
  21. * 在MacOS下可以使用avfoundation读取摄像头设备。
  22. *
  23. * This software read data from Computer's Camera and play it.
  24. * It's the simplest example about usage of FFmpeg's libavdevice Library.
  25. * It's suiltable for the beginner of FFmpeg.
  26. * This software support 2 methods to read camera in Microsoft Windows:
  27. *  1.gdigrab: VfW (Video for Windows) capture input device.
  28. *             The filename passed as input is the capture driver number,
  29. *             ranging from 0 to 9.
  30. *  2.dshow: Use Directshow. Camera's name in author's computer is
  31. *             "Integrated Camera".
  32. * It use video4linux2 to read Camera in Linux.
  33. * It use avfoundation to read Camera in MacOS.
  34. *
  35. */
  36. #include <stdio.h>
  37. #define __STDC_CONSTANT_MACROS
  38. #ifdef _WIN32
  39. //Windows
  40. extern "C"
  41. {
  42. #include "libavcodec/avcodec.h"
  43. #include "libavformat/avformat.h"
  44. #include "libswscale/swscale.h"
  45. #include "libavdevice/avdevice.h"
  46. #include "SDL/SDL.h"
  47. };
  48. #else
  49. //Linux...
  50. #ifdef __cplusplus
  51. extern "C"
  52. {
  53. #endif
  54. #include <libavcodec/avcodec.h>
  55. #include <libavformat/avformat.h>
  56. #include <libswscale/swscale.h>
  57. #include <libavdevice/avdevice.h>
  58. #include <SDL/SDL.h>
  59. #ifdef __cplusplus
  60. };
  61. #endif
  62. #endif
  63. //Output YUV420P
  64. #define OUTPUT_YUV420P 0
  65. //'1' Use Dshow
  66. //'0' Use VFW
  67. #define USE_DSHOW 0
  68. //Refresh Event
  69. #define SFM_REFRESH_EVENT  (SDL_USEREVENT + 1)
  70. #define SFM_BREAK_EVENT  (SDL_USEREVENT + 2)
  71. int thread_exit=0;
  72. int sfp_refresh_thread(void *opaque)
  73. {
  74. thread_exit=0;
  75. while (!thread_exit) {
  76. SDL_Event event;
  77. event.type = SFM_REFRESH_EVENT;
  78. SDL_PushEvent(&event);
  79. SDL_Delay(40);
  80. }
  81. thread_exit=0;
  82. //Break
  83. SDL_Event event;
  84. event.type = SFM_BREAK_EVENT;
  85. SDL_PushEvent(&event);
  86. return 0;
  87. }
  88. //Show Dshow Device
  89. void show_dshow_device(){
  90. AVFormatContext *pFormatCtx = avformat_alloc_context();
  91. AVDictionary* options = NULL;
  92. av_dict_set(&options,"list_devices","true",0);
  93. AVInputFormat *iformat = av_find_input_format("dshow");
  94. printf("========Device Info=============\n");
  95. avformat_open_input(&pFormatCtx,"video=dummy",iformat,&options);
  96. printf("================================\n");
  97. }
  98. //Show Dshow Device Option
  99. void show_dshow_device_option(){
  100. AVFormatContext *pFormatCtx = avformat_alloc_context();
  101. AVDictionary* options = NULL;
  102. av_dict_set(&options,"list_options","true",0);
  103. AVInputFormat *iformat = av_find_input_format("dshow");
  104. printf("========Device Option Info======\n");
  105. avformat_open_input(&pFormatCtx,"video=Integrated Camera",iformat,&options);
  106. printf("================================\n");
  107. }
  108. //Show VFW Device
  109. void show_vfw_device(){
  110. AVFormatContext *pFormatCtx = avformat_alloc_context();
  111. AVInputFormat *iformat = av_find_input_format("vfwcap");
  112. printf("========VFW Device Info======\n");
  113. avformat_open_input(&pFormatCtx,"list",iformat,NULL);
  114. printf("=============================\n");
  115. }
  116. //Show AVFoundation Device
  117. void show_avfoundation_device(){
  118. AVFormatContext *pFormatCtx = avformat_alloc_context();
  119. AVDictionary* options = NULL;
  120. av_dict_set(&options,"list_devices","true",0);
  121. AVInputFormat *iformat = av_find_input_format("avfoundation");
  122. printf("==AVFoundation Device Info===\n");
  123. avformat_open_input(&pFormatCtx,"",iformat,&options);
  124. printf("=============================\n");
  125. }
  126. int main(int argc, char* argv[])
  127. {
  128. AVFormatContext *pFormatCtx;
  129. int             i, videoindex;
  130. AVCodecContext  *pCodecCtx;
  131. AVCodec         *pCodec;
  132. av_register_all();
  133. avformat_network_init();
  134. pFormatCtx = avformat_alloc_context();
  135. //Open File
  136. //char filepath[]="src01_480x272_22.h265";
  137. //avformat_open_input(&pFormatCtx,filepath,NULL,NULL)
  138. //Register Device
  139. avdevice_register_all();
  140. //Windows
  141. #ifdef _WIN32
  142. //Show Dshow Device
  143. show_dshow_device();
  144. //Show Device Options
  145. show_dshow_device_option();
  146. //Show VFW Options
  147. show_vfw_device();
  148. #if USE_DSHOW
  149. AVInputFormat *ifmt=av_find_input_format("dshow");
  150. //Set own video device's name
  151. if(avformat_open_input(&pFormatCtx,"video=Integrated Camera",ifmt,NULL)!=0){
  152. printf("Couldn't open input stream.\n");
  153. return -1;
  154. }
  155. #else
  156. AVInputFormat *ifmt=av_find_input_format("vfwcap");
  157. if(avformat_open_input(&pFormatCtx,"0",ifmt,NULL)!=0){
  158. printf("Couldn't open input stream.\n");
  159. return -1;
  160. }
  161. #endif
  162. #elif defined linux
  163. //Linux
  164. AVInputFormat *ifmt=av_find_input_format("video4linux2");
  165. if(avformat_open_input(&pFormatCtx,"/dev/video0",ifmt,NULL)!=0){
  166. printf("Couldn't open input stream.\n");
  167. return -1;
  168. }
  169. #else
  170. show_avfoundation_device();
  171. //Mac
  172. AVInputFormat *ifmt=av_find_input_format("avfoundation");
  173. //Avfoundation
  174. //[video]:[audio]
  175. if(avformat_open_input(&pFormatCtx,"0",ifmt,NULL)!=0){
  176. printf("Couldn't open input stream.\n");
  177. return -1;
  178. }
  179. #endif
  180. if(avformat_find_stream_info(pFormatCtx,NULL)<0)
  181. {
  182. printf("Couldn't find stream information.\n");
  183. return -1;
  184. }
  185. videoindex=-1;
  186. for(i=0; i<pFormatCtx->nb_streams; i++)
  187. if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
  188. {
  189. videoindex=i;
  190. break;
  191. }
  192. if(videoindex==-1)
  193. {
  194. printf("Couldn't find a video stream.\n");
  195. return -1;
  196. }
  197. pCodecCtx=pFormatCtx->streams[videoindex]->codec;
  198. pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  199. if(pCodec==NULL)
  200. {
  201. printf("Codec not found.\n");
  202. return -1;
  203. }
  204. if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
  205. {
  206. printf("Could not open codec.\n");
  207. return -1;
  208. }
  209. AVFrame *pFrame,*pFrameYUV;
  210. pFrame=av_frame_alloc();
  211. pFrameYUV=av_frame_alloc();
  212. //unsigned char *out_buffer=(unsigned char *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
  213. //avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
  214. //SDL----------------------------
  215. if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
  216. printf( "Could not initialize SDL - %s\n", SDL_GetError());
  217. return -1;
  218. }
  219. int screen_w=0,screen_h=0;
  220. SDL_Surface *screen;
  221. screen_w = pCodecCtx->width;
  222. screen_h = pCodecCtx->height;
  223. screen = SDL_SetVideoMode(screen_w, screen_h, 0,0);
  224. if(!screen) {
  225. printf("SDL: could not set video mode - exiting:%s\n",SDL_GetError());
  226. return -1;
  227. }
  228. SDL_Overlay *bmp;
  229. bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,SDL_YV12_OVERLAY, screen);
  230. SDL_Rect rect;
  231. rect.x = 0;
  232. rect.y = 0;
  233. rect.w = screen_w;
  234. rect.h = screen_h;
  235. //SDL End------------------------
  236. int ret, got_picture;
  237. AVPacket *packet=(AVPacket *)av_malloc(sizeof(AVPacket));
  238. #if OUTPUT_YUV420P
  239. FILE *fp_yuv=fopen("output.yuv","wb+");
  240. #endif
  241. struct SwsContext *img_convert_ctx;
  242. img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
  243. //------------------------------
  244. SDL_Thread *video_tid = SDL_CreateThread(sfp_refresh_thread,NULL);
  245. //
  246. SDL_WM_SetCaption("Simplest FFmpeg Read Camera",NULL);
  247. //Event Loop
  248. SDL_Event event;
  249. for (;;) {
  250. //Wait
  251. SDL_WaitEvent(&event);
  252. if(event.type==SFM_REFRESH_EVENT){
  253. //------------------------------
  254. if(av_read_frame(pFormatCtx, packet)>=0){
  255. if(packet->stream_index==videoindex){
  256. ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
  257. if(ret < 0){
  258. printf("Decode Error.\n");
  259. return -1;
  260. }
  261. if(got_picture){
  262. SDL_LockYUVOverlay(bmp);
  263. pFrameYUV->data[0]=bmp->pixels[0];
  264. pFrameYUV->data[1]=bmp->pixels[2];
  265. pFrameYUV->data[2]=bmp->pixels[1];
  266. pFrameYUV->linesize[0]=bmp->pitches[0];
  267. pFrameYUV->linesize[1]=bmp->pitches[2];
  268. pFrameYUV->linesize[2]=bmp->pitches[1];
  269. sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
  270. #if OUTPUT_YUV420P
  271. int y_size=pCodecCtx->width*pCodecCtx->height;
  272. fwrite(pFrameYUV->data[0],1,y_size,fp_yuv);    //Y
  273. fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv);  //U
  274. fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv);  //V
  275. #endif
  276. SDL_UnlockYUVOverlay(bmp);
  277. SDL_DisplayYUVOverlay(bmp, &rect);
  278. }
  279. }
  280. av_free_packet(packet);
  281. }else{
  282. //Exit Thread
  283. thread_exit=1;
  284. }
  285. }else if(event.type==SDL_QUIT){
  286. thread_exit=1;
  287. }else if(event.type==SFM_BREAK_EVENT){
  288. break;
  289. }
  290. }
  291. sws_freeContext(img_convert_ctx);
  292. #if OUTPUT_YUV420P
  293. fclose(fp_yuv);
  294. #endif
  295. SDL_Quit();
  296. //av_free(out_buffer);
  297. av_free(pFrameYUV);
  298. avcodec_close(pCodecCtx);
  299. avformat_close_input(&pFormatCtx);
  300. return 0;
  301. }

结果

程序的运行效果如下。输出了摄像头的数据。

可以通过下面的宏定义来确定是否将解码后的YUV420P数据输出成文件:

  1. #define OUTPUT_YUV420P 0

可以通过下面的宏定义来确定使用VFW或者是Dshow打开摄像头:

  1. //'1' Use Dshow
  2. //'0' Use VFW
  3. #define USE_DSHOW 0

下载

 

Simplest FFmpeg Device 

项目主页

SourceForge:https://sourceforge.net/projects/simplestffmpegdevice/

Github:https://github.com/leixiaohua1020/simplest_ffmpeg_device

开源中国:http://git.oschina.net/leixiaohua1020/simplest_ffmpeg_device

CSDN下载地址:

http://download.csdn.net/detail/leixiaohua1020/7994049

注:

本工程包含两个基于FFmpeg的libavdevice的例子:
 simplest_ffmpeg_grabdesktop:屏幕录制。
 simplest_ffmpeg_readcamera:读取摄像头。

更新-1.1(2015.1.9)=========================================

该版本中,修改了SDL的显示方式,弹出的窗口可以移动了。

CSDN下载地址:http://download.csdn.net/detail/leixiaohua1020/8344695

更新-1.2 (2015.2.13)=========================================

这次考虑到了跨平台的要求,调整了源代码。经过这次调整之后,源代码可以在以下平台编译通过:

VC++:打开sln文件即可编译,无需配置。

cl.exe:打开compile_cl.bat即可命令行下使用cl.exe进行编译,注意可能需要按照VC的安装路径调整脚本里面的参数。编译命令如下。

  1. ::VS2010 Environment
  2. call "D:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
  3. ::include
  4. @set INCLUDE=include;%INCLUDE%
  5. ::lib
  6. @set LIB=lib;%LIB%
  7. ::compile and link
  8. cl simplest_ffmpeg_readcamera.cpp /MD /link SDL.lib SDLmain.lib avcodec.lib ^
  9. avformat.lib avutil.lib avdevice.lib avfilter.lib postproc.lib swresample.lib swscale.lib ^
  10. /SUBSYSTEM:WINDOWS /OPT:NOREF

MinGW:MinGW命令行下运行compile_mingw.sh即可使用MinGW的g++进行编译。编译命令如下。

  1. g++ simplest_ffmpeg_readcamera.cpp -g -o simplest_ffmpeg_readcamera.exe \
  2. -I /usr/local/include -L /usr/local/lib \
  3. -lmingw32 -lSDLmain -lSDL -lavformat -lavcodec -lavutil -lavdevice -lswscale

GCC(Linux):Linux命令行下运行compile_gcc.sh即可使用GCC进行编译。编译命令如下。

  1. gcc simplest_ffmpeg_readcamera.cpp -g -o simplest_ffmpeg_readcamera.out \
  2. -I /usr/local/include -L /usr/local/lib -lSDLmain -lSDL -lavformat -lavcodec -lavutil -lavdevice -lswscale

GCC(MacOS):MacOS命令行下运行compile_gcc_mac.sh即可使用GCC进行编译。Mac的GCC和Linux的GCC差别不大,但是使用SDL1.2的时候,必须加上“-framework Cocoa”参数,否则编译无法通过。编译命令如下。

  1. gcc simplest_ffmpeg_readcamera.cpp -g -o simplest_ffmpeg_readcamera.out \
  2. -framework Cocoa -I /usr/local/include -L /usr/local/lib -lSDLmain -lSDL -lavformat -lavcodec -lavutil -lavdevice -lswscale

PS:相关的编译命令已经保存到了工程文件夹中

此外,增加了MacOS下使用avfoundation读取摄像头的代码。

CSDN下载地址:http://download.csdn.net/detail/leixiaohua1020/8445747

SourceForge上已经更新。

最简单的基于FFmpeg的AVDevice例子(读取摄像头)【转】的更多相关文章

  1. 最简单的基于FFmpeg的AVDevice例子(屏幕录制)

    =====================================================最简单的基于FFmpeg的AVDevice例子文章列表: 最简单的基于FFmpeg的AVDev ...

  2. 最简单的基于FFmpeg的AVDevice例子(读取摄像头)

    =====================================================最简单的基于FFmpeg的AVDevice例子文章列表: 最简单的基于FFmpeg的AVDev ...

  3. [转载] 最简单的基于FFmpeg的AVDevice例子(读取摄像头)

    =====================================================最简单的基于FFmpeg的AVDevice例子文章列表: 最简单的基于FFmpeg的AVDev ...

  4. 最简单的基于FFmpeg的AVfilter例子(水印叠加)

    ===================================================== 最简单的基于FFmpeg的AVfilter例子系列文章: 最简单的基于FFmpeg的AVfi ...

  5. 最简单的基于FFmpeg的AVDevice样例(读取摄像头)

    =====================================================最简单的基于FFmpeg的AVDevice样例文章列表: 最简单的基于FFmpeg的AVDev ...

  6. 最简单的基于FFMPEG的转码程序

    本文介绍一个简单的基于FFmpeg的转码器.它可以将一种视频格式(包括封转格式和编码格式)转换为另一种视频格式.转码器在视音频编解码处理的程序中,属于一个比较复杂的东西.因为它结合了视频的解码和编码. ...

  7. 最简单的基于FFmpeg的内存读写的例子:内存转码器

    ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的 ...

  8. 最简单的基于FFmpeg的内存读写的例子:内存播放器

    ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的 ...

  9. (转)最简单的基于FFmpeg的内存读写的例子:内存播放器

    ffmpeg内存播放解码 目录(?)[+] ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章 ...

随机推荐

  1. java练习题——数组

    上述代码可以顺利通过编译,并且输出一个“很奇怪”的结果:[Ljava.lang.Object;@2a139a55 为什么会出现这种情况? 直接输出object的对象,系统会输出地址,如果想要输出其中的 ...

  2. CSS计数器(自定义列表)

    概念 CSS3计数器(CSS Counters)可以允许我们使用css对页面中的任意元素进行计数,实现类似于有序列表的功能(自定义有序列表) 与有序列表相比,它的突出特性在于可以对任意元素计数,同时实 ...

  3. Atom使用插件精选(FE)

    [转]原文https://zhuanlan.zhihu.com/p/24753739?refer=AlenQi Atom琳琅满目的插件中,为前端coder推荐一些实用的插件. sync-setting ...

  4. 开启虚拟机所报的错误:VMware Workstation cannot connect to the virtual machine. Make sure you have rights to run the program, access all directories the program uses, and access all directories for temporary fil

    当我们开启虚拟机时出现错误: VMware Workstation cannot connect to the virtual machine. Make sure you have rights t ...

  5. vue-cli 引入axios

    写文章注册登录     首页 下载App × vue-cli 引入axios及跨域使用 星球小霸王 关注 2017.10.04 16:40* 字数 504 阅读 13038评论 2喜欢 18 使用 c ...

  6. Java算法求最大最小值,倒序,冒泡排序,斐波纳契数列,日历一些经典算法

    一,求最大,最小值 int[] a={21,31,4,2,766,345,2,34}; //这里防止数组中有负数,所以初始化的时候给的数组中的第一个数. int max=a[0]; int min=a ...

  7. 图解java面试

    图解Java面试题:基本语法 2017-02-07 14:34 出处:清屏网 人气:178 评论(0)   内容大纲.png &和&&的区别 &和&&的 ...

  8. 《1024伐木累-周末特别篇》-中彩票了,开发APP

    本周发布的<1024伐木累>,受到了很多码汪们的好评,博主在这里感谢大家的支持,同时,博主临时起意,增加一期周末对话特别篇,让大家在“满血复活”的时间里,充分感受快乐的味道~ 1.中彩票 ...

  9. 关于Ckpalyer播放器的MP4无法播放问题

    此文是从网上摘要的 有时在本地使用ckplayer来播放视频,flv格式非常容易的就播放了,但是使用mp4格式却显示:加载失败.为什么呢?        首页看下你i的本地站点MIME类型中,是否增加 ...

  10. CentOS vim中backspace不能用,出现^?的解决方法

    查看在VI配置器下面使用backspace删除时提示输出那个字符例如:^H.^?.^a等字符如果输出的是:^? 字符 则使用以下命令:[oracle@junyii~]$ stty erase ^? 再 ...