好多开发者提到,RTMP播放器,不知道有哪些对标和考察指标,以下大概聊聊我们的一点经验,感兴趣的,可以关注 github

1. 低延迟:大多数RTMP的播放都面向直播场景,如果延迟过大,严重影响体验,所以,低延迟是衡量一个好的RTMP播放器非常重要的指标,目前大牛直播SDK的RTMP直播播放延迟比开源播放器更优异(大牛直播SDK延迟在1秒左右,开源播放器如VLC,延迟在5-7秒),而且长时间运行下,大牛直播SDK播放端不会造成延迟累积,开源或第三方播放器,长时间运行,容易产生延迟累积;

部分服务器会缓存GOP,确保快速实现首屏播放,又不影响延迟,对此,我们设计了快速启动接口,快速render第一帧的同时,追到最新的播放数据:

  1. /*
  2. * 设置秒开, 1为秒开, 0为不秒开
  3. */
  4. [DllImport(@"SmartPlayerSDK.dll")]
  5. public static extern UInt32 NT_SP_SetFastStartup(IntPtr handle, Int32 isFastStartup);

2. 音视频同步处理大多播放器为了追求低延迟,甚至不做音视频同步,拿到audio video直接播放,导致a/v不同步,还有就是时间戳乱跳等各种问题,大牛直播SDK提供的播放器,具备好的时间戳同步和异常时间戳矫正机制;

备注:如果是超低延迟模式下,可以0 buffer,不做音视频同步:

  1. /*
  2. * 设置低延时播放模式,默认是正常播放模式
  3. * mode: 1为低延时模式, 0为正常模式,其他只无效
  4. * 接口调用成功返回NT_ERC_OK
  5. */
  6. [DllImport(@"SmartPlayerSDK.dll")]
  7. public static extern UInt32 NT_SP_SetLowLatencyMode(IntPtr handle, Int32 mode);

3. 支持多实例:大牛直播SDK提供的RTMP直播播放SDK支持在设备性能允许的情况下,支持多实例播放RTMP流数据,大多开源播放器对多实例支持不太友好;

除了常规的多实例外,比如大屏监控场景下,尽管我们CPU占用已经是行业内非常低的了,但是好多厂家下,不是每路都需要全帧播放,针对此种情况,我们做了实时只播放关键帧和全帧播放的接口设计,比如8个实例,其中不太重要的几路数据,可以设置只播放关键帧,需要重点关注时,点击全帧率播放即可,这样既节省了系统开销,又实现了多路播放的目的:

  1. /*
  2. * 设置只解码视频关键帧
  3. * is_only_dec_key_frame: 1:表示只解码关键帧, 0:表示都解码, 默认是0
  4. * 成功返回NT_ERC_OK
  5. */
  6. [DllImport(@"SmartPlayerSDK.dll")]
  7. public static extern UInt32 NT_SP_SetOnlyDecodeVideoKeyFrame(IntPtr handle, Int32 is_only_dec_key_frame);

4. 支持buffer time设置:在一些有网络抖动的场景,播放器需要支持buffer time设置,一般来说,以毫秒计,开源播放器对此支持不够友好;

5. 实时静音:比如,多窗口播放RTMP流,如果每个audio都播放出来,体验非常不好,所以实时静音功能非常必要,开源播放器不具备实时静音功能;

6. 视频view旋转:好多摄像头由于安装限制,导致图像倒置,所以一个好的RTMP播放器应该支持如视频view实时旋转(0° 90° 180° 270°)、水平反转、垂直反转,开源或第三方播放器不具备此功能;

  1. /*
  2. *上下反转(垂直反转)
  3. *is_flip: 1:表示反转, 0:表示不反转
  4. */
  5. [DllImport(@"SmartPlayerSDK.dll")]
  6. public static extern UInt32 NT_SP_SetFlipVertical(IntPtr handle, Int32 is_flip);
  7. /*
  8. *水平反转
  9. *is_flip: 1:表示反转, 0:表示不反转
  10. */
  11. [DllImport(@"SmartPlayerSDK.dll")]
  12. public static extern UInt32 NT_SP_SetFlipHorizontal(IntPtr handle, Int32 is_flip);
  13. /*
  14. * 设置旋转,顺时针旋转
  15. * degress: 设置0, 90, 180, 270度有效,其他值无效
  16. * 注意:除了0度,其他角度播放会耗费更多CPU
  17. * 接口调用成功返回NT_ERC_OK
  18. */
  19. [DllImport(@"SmartPlayerSDK.dll")]
  20. public static extern UInt32 NT_SP_SetRotation(IntPtr handle, Int32 degress);

7. 支持解码后audio/video数据输出:大牛直播SDK接触到好多开发者,希望能在播放的同时,获取到YUV或RGB数据,进行人脸匹配等算法分析,开源播放器不具备此功能;

  1. public void SDKVideoFrameCallBack(UInt32 status, NT_SP_VideoFrame frame)
  2. {
  3. if (cur_video_frame_.plane0_ != IntPtr.Zero)
  4. {
  5. Marshal.FreeHGlobal(cur_video_frame_.plane0_);
  6. cur_video_frame_.plane0_ = IntPtr.Zero;
  7. }
  8. cur_video_frame_ = frame;
  9. this.Invalidate();
  10. }
  11. public void SDKAudioPCMFrameCallBack(UInt32 status, IntPtr data, UInt32 size,
  12. Int32 sample_rate, Int32 channel, Int32 per_channel_sample_number)
  13. {
  14. //这里拿到回调的PCM frame,进行相关操作(如自己播放)
  15. //label_debug.Text = per_channel_sample_number.ToString();
  16. //release
  17. Marshal.FreeHGlobal(data);
  18. }
  19. public void SetVideoFrameCallBack(IntPtr handle, IntPtr userData, UInt32 status, IntPtr frame)
  20. {
  21. if (frame == IntPtr.Zero)
  22. {
  23. return;
  24. }
  25. //如需直接处理RGB数据,请参考以下流程
  26. NT_SP_VideoFrame video_frame = (NT_SP_VideoFrame)Marshal.PtrToStructure(frame, typeof(NT_SP_VideoFrame));
  27. NT_SP_VideoFrame pVideoFrame = new NT_SP_VideoFrame();
  28. pVideoFrame.format_ = video_frame.format_;
  29. pVideoFrame.width_ = video_frame.width_;
  30. pVideoFrame.height_ = video_frame.height_;
  31. pVideoFrame.timestamp_ = video_frame.timestamp_;
  32. pVideoFrame.stride0_ = video_frame.stride0_;
  33. pVideoFrame.stride1_ = video_frame.stride1_;
  34. pVideoFrame.stride2_ = video_frame.stride2_;
  35. pVideoFrame.stride3_ = video_frame.stride3_;
  36. Int32 argb_size = video_frame.stride0_ * video_frame.height_;
  37. pVideoFrame.plane0_ = Marshal.AllocHGlobal(argb_size);
  38. CopyMemory(pVideoFrame.plane0_, video_frame.plane0_, (UInt32)argb_size);
  39. if (playWnd.InvokeRequired)
  40. {
  41. BeginInvoke(set_video_frame_call_back_, status, pVideoFrame);
  42. }
  43. else
  44. {
  45. set_video_frame_call_back_(status, pVideoFrame);
  46. }
  47. }
  48. public void SetAudioPCMFrameCallBack(IntPtr handle, IntPtr user_data,
  49. UInt32 status, IntPtr data, UInt32 size,
  50. Int32 sample_rate, Int32 channel, Int32 per_channel_sample_number)
  51. {
  52. if (data == IntPtr.Zero || size == 0)
  53. {
  54. return;
  55. }
  56. IntPtr pcmData = Marshal.AllocHGlobal((Int32)size);
  57. CopyMemory(pcmData, data, (UInt32)size);
  58. if (playWnd.InvokeRequired)
  59. {
  60. BeginInvoke(set_audio_pcm_frame_call_back_, status, pcmData, size, sample_rate, channel, per_channel_sample_number);
  61. }
  62. else
  63. {
  64. set_audio_pcm_frame_call_back_(status, pcmData, size, sample_rate, channel, per_channel_sample_number);
  65. }
  66. }

8. 实时快照:感兴趣或重要的画面,实时截取下来非常必要,一般播放器不具备快照能力,开源播放器不具备此功能;

  1. /*
  2. * 捕获图片
  3. * file_name_utf8: 文件名称,utf8编码
  4. * call_back_data: 回调时用户自定义数据
  5. * call_back: 回调函数,用来通知用户截图已经完成或者失败
  6. * 成功返回 NT_ERC_OK
  7. * 只有在播放时调用才可能成功,其他情况下调用,返回错误.
  8. * 因为生成PNG文件比较耗时,一般需要几百毫秒,为防止CPU过高,SDK会限制截图请求数量,当超过一定数量时,
  9. * 调用这个接口会返回NT_ERC_SP_TOO_MANY_CAPTURE_IMAGE_REQUESTS. 这种情况下, 请延时一段时间,等SDK处理掉一些请求后,再尝试.
  10. */
  11. [DllImport(@"SmartPlayerSDK.dll")]
  12. public static extern UInt32 NT_SP_CaptureImage(IntPtr handle, IntPtr file_name_utf8,
  13. IntPtr call_back_data, SP_SDKCaptureImageCallBack call_back);
  14. public void SDKCaptureImageCallBack(IntPtr handle, IntPtr userData, UInt32 result, IntPtr file_name)
  15. {
  16. if (file_name == IntPtr.Zero)
  17. return;
  18. int index = 0;
  19. while (true)
  20. {
  21. if (0 == Marshal.ReadByte(file_name, index))
  22. break;
  23. index++;
  24. }
  25. byte[] file_name_buffer = new byte[index];
  26. Marshal.Copy(file_name, file_name_buffer, 0, index);
  27. byte[] dst_buffer = Encoding.Convert(Encoding.UTF8, Encoding.Default, file_name_buffer, 0, file_name_buffer.Length);
  28. String image_name = Encoding.Default.GetString(dst_buffer, 0, dst_buffer.Length);
  29. if (playWnd.InvokeRequired)
  30. {
  31. BeginInvoke(set_capture_image_call_back_, result, image_name);
  32. }
  33. else
  34. {
  35. set_capture_image_call_back_(result, image_name);
  36. }
  37. }

9. 网络抖动处理(如断网重连):稳定的网络处理机制、支持如断网重连等,开源播放器对网络异常处理支持较差;

  1. /*事件ID*/
  2. public enum NT_SP_E_EVENT_ID : uint
  3. {
  4. NT_SP_E_EVENT_ID_BASE = NTBaseCodeDefine.NT_EVENT_ID_SMART_PLAYER_SDK,
  5. NT_SP_E_EVENT_ID_CONNECTING = NT_SP_E_EVENT_ID_BASE | 0x2, /*连接中*/
  6. NT_SP_E_EVENT_ID_CONNECTION_FAILED = NT_SP_E_EVENT_ID_BASE | 0x3, /*连接失败*/
  7. NT_SP_E_EVENT_ID_CONNECTED = NT_SP_E_EVENT_ID_BASE | 0x4, /*已连接*/
  8. NT_SP_E_EVENT_ID_DISCONNECTED = NT_SP_E_EVENT_ID_BASE | 0x5, /*断开连接*/
  9. NT_SP_E_EVENT_ID_NO_MEDIADATA_RECEIVED = NT_SP_E_EVENT_ID_BASE | 0x8, /*收不到RTMP数据*/
  10. NT_SP_E_EVENT_ID_RTSP_STATUS_CODE = NT_SP_E_EVENT_ID_BASE | 0xB, /*rtsp status code上报, 目前只上报401, param1表示status code*/
  11. /* 接下来请从0x81开始*/
  12. NT_SP_E_EVENT_ID_START_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x81, /*开始缓冲*/
  13. NT_SP_E_EVENT_ID_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x82, /*缓冲中, param1 表示百分比进度*/
  14. NT_SP_E_EVENT_ID_STOP_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x83, /*停止缓冲*/
  15. NT_SP_E_EVENT_ID_DOWNLOAD_SPEED = NT_SP_E_EVENT_ID_BASE | 0x91, /*下载速度, param1表示下载速度,单位是(Byte/s)*/
  16. NT_SP_E_EVENT_ID_PLAYBACK_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa1, /*播放结束, 直播流没有这个事件,点播流才有*/
  17. NT_SP_E_EVENT_ID_RECORDER_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa2, /*录像结束, 直播流没有这个事件, 点播流才有*/
  18. NT_SP_E_EVENT_ID_PULLSTREAM_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa3, /*拉流结束, 直播流没有这个事件,点播流才有*/
  19. NT_SP_E_EVENT_ID_DURATION = NT_SP_E_EVENT_ID_BASE | 0xa8, /*视频时长,如果是直播,则不上报,如果是点播的话, 若能从视频源获取视频时长的话,则上报, param1表示视频时长,单位是毫秒(ms)*/
  20. }

10. 长期运行稳定性:大牛直播SDK提供的RTMP直播播放SDK适用于长时间运行,开源播放器对长时间运行稳定性支持较差;

11. 实时下载速度反馈:大牛直播SDK提供音视频流实时下载回调,并可设置回调时间间隔,确保实时下载速度反馈,以此来监听网络状态,开源播放器不具备此能力;

  1. /*
  2. * 设置下载速度上报, 默认不上报下载速度
  3. * is_report: 上报开关, 1: 表上报. 0: 表示不上报. 其他值无效.
  4. * report_interval: 上报时间间隔(上报频率),单位是秒,最小值是1秒1次. 如果小于1且设置了上报,将调用失败
  5. * 注意:如果设置上报的话,请设置SetEventCallBack, 然后在回调函数里面处理这个事件.
  6. * 上报事件是:NT_SP_E_EVENT_ID_DOWNLOAD_SPEED
  7. * 这个接口必须在StartXXX之前调用
  8. * 成功返回NT_ERC_OK
  9. */
  10. [DllImport(@"SmartPlayerSDK.dll")]
  11. public static extern UInt32 NT_SP_SetReportDownloadSpeed(IntPtr handle, Int32 is_report, Int32 report_interval);
  12. /*
  13. * 主动获取下载速度
  14. * speed: 返回下载速度,单位是Byte/s
  15. * (注意:这个接口必须在startXXX之后调用,否则会失败)
  16. * 成功返回NT_ERC_OK
  17. */
  18. [DllImport(@"SmartPlayerSDK.dll")]
  19. public static extern UInt32 NT_SP_GetDownloadSpeed(IntPtr handle, ref Int32 speed);

12. 异常状态处理Event状态回调如播放的过程中断网,大牛直播SDK提供的播放器可实时回调相关状态,确保上层模块感知处理,开源播放器对此支持不好;

  1. /*
  2. * 设置事件回调,如果想监听事件的话,建议调用Open成功后,就调用这个接口
  3. */
  4. [DllImport(@"SmartPlayerSDK.dll")]
  5. public static extern UInt32 NT_SP_SetEventCallBack(IntPtr handle, IntPtr call_back_data, SP_SDKEventCallBack call_back);
  6. /*
  7. * 设置视频大小回调接口
  8. */
  9. [DllImport(@"SmartPlayerSDK.dll")]
  10. public static extern UInt32 NT_SP_SetVideoSizeCallBack(IntPtr handle, IntPtr callbackdata, SP_SDKVideoSizeCallBack call_back);
  11. /*
  12. * 设置视频回调, 吐视频数据出来
  13. * frame_format: 只能是NT_SP_E_VIDEO_FRAME_FORMAT_RGB32, NT_SP_E_VIDEO_FRAME_FROMAT_I420
  14. */
  15. [DllImport(@"SmartPlayerSDK.dll")]
  16. public static extern UInt32 NT_SP_SetVideoFrameCallBack(IntPtr handle, Int32 frame_format,
  17. IntPtr callbackdata, SP_SDKVideoFrameCallBack call_back);
  18. /*
  19. * 设置视频回调, 吐视频数据出来, 可以指定吐出来的视频宽高
  20. * handle: 播放句柄
  21. * scale_width:缩放宽度(必须是偶数,建议是 16 的倍数)
  22. * scale_height:缩放高度(必须是偶数)
  23. * scale_filter_mode: 缩放质量, 0 的话 SDK 将使用默认值, 目前可设置范围为[1, 3], 值越大 缩放质量越好,但越耗性能
  24. * frame_format: 只能是NT_SP_E_VIDEO_FRAME_FORMAT_RGB32, NT_SP_E_VIDEO_FRAME_FROMAT_I420
  25. * 成功返回NT_ERC_OK
  26. */
  27. [DllImport(@"SmartPlayerSDK.dll")]
  28. public static extern UInt32 NT_SP_SetVideoFrameCallBackV2(IntPtr handle,
  29. Int32 scale_width, Int32 scale_height,
  30. Int32 scale_filter_mode, Int32 frame_format,
  31. IntPtr call_back_data, SP_SDKVideoFrameCallBack call_back);
  32. /*
  33. * 设置绘制视频帧时,视频帧时间戳回调
  34. * 注意如果当前播放流是纯音频,那么将不会回调,这个仅在有视频的情况下才有效
  35. */
  36. [DllImport(@"SmartPlayerSDK.dll")]
  37. public static extern UInt32 NT_SP_SetRenderVideoFrameTimestampCallBack(IntPtr handle,
  38. IntPtr callbackdata, SP_SDKRenderVideoFrameTimestampCallBack call_back);
  39. /*
  40. * 设置音频PCM帧回调, 吐PCM数据出来,目前每帧大小是10ms.
  41. */
  42. [DllImport(@"SmartPlayerSDK.dll")]
  43. public static extern UInt32 NT_SP_SetAudioPCMFrameCallBack(IntPtr handle,
  44. IntPtr call_back_data, SP_SDKAudioPCMFrameCallBack call_back);
  45. /*
  46. * 设置用户数据回调
  47. */
  48. [DllImport(@"SmartPlayerSDK.dll")]
  49. public static extern UInt32 NT_SP_SetUserDataCallBack(IntPtr handle,
  50. IntPtr call_back_data, SP_SDKUserDataCallBack call_back);
  51. /*
  52. * 设置视频sei数据回调
  53. */
  54. [DllImport(@"SmartPlayerSDK.dll")]
  55. public static extern UInt32 NT_SP_SetSEIDataCallBack(IntPtr handle,
  56. IntPtr call_back_data, SP_SDKSEIDataCallBack call_back);

13. 设置视频填充模式(等比例显示):好多情况下,有些场景需要全view铺满播放,有些为了防止视频拉伸,可以设置成等比例缩放显示;

  1. /*
  2. * 设置视频画面的填充模式,如填充整个绘制窗口、等比例填充绘制窗口,如不设置,默认填充整个绘制窗口
  3. * handle: 播放句柄
  4. * mode: 0: 填充整个绘制窗口; 1: 等比例填充绘制窗口, 默认值是0
  5. * 成功返回NT_ERC_OK
  6. */
  7. [DllImport(@"SmartPlayerSDK.dll")]
  8. public static extern UInt32 NT_SP_SetRenderScaleMode(IntPtr handle, Int32 mode);

14. D3D检测:一般来说市面上的大多Windows都支持D3D,有些小众化的,只支持GDI模式绘制,所以为了更好的兼容性,这个接口非常必要。

  1. /*
  2. * handle: 播放句柄
  3. * hwnd: 这个要传入真正用来绘制的窗口句柄
  4. * is_support: 如果支持的话 *is_support 为1, 不支持的话为0
  5. * 接口调用成功返回NT_ERC_OK
  6. */
  7. [DllImport(@"SmartPlayerSDK.dll")]
  8. public static extern UInt32 NT_SP_IsSupportD3DRender(IntPtr handle, IntPtr hwnd, ref Int32 is_support);

开发个RTMP播放器居然这么难?RTMP播放器对标和考察指标的更多相关文章

  1. 最简单的基于Flash的流媒体示例:网页播放器(HTTP,RTMP,HLS)

    http://blog.csdn.net/leixiaohua1020/article/details/43936415 ======================================= ...

  2. 我们计划为EasyDSS定制开发一款超低延时的EasyPlayer Flash播放器

    现象 最近团队在做EasyDSS RTMP流媒体服务器开发的过程中,遇到了一个关于延时累积的问题,先大概描述一下过程: 在EasyRTMP Android进行长时间的RTMP推流压力测试,在EasyD ...

  3. 夺命雷公狗---微信开发59----在线点播电影网1之ckplayer播放器

    我们节课程就要开始写一个小项目了,这项目主要是写一个在线点播电影影网的,我们用到的播放器是ckplayer ckplayer基本介绍: ckplayer的全称是:超酷flv播放器,他是一款用于网页上播 ...

  4. Android 视频播放器 (三):使用NBPlayer播放直播视频

    一.前言 在 Android 音视频开发学习思路 中,我们不断的学习和了解音视频相关的知识,随着知识点不断的学习,我们现在应该做的事情,就是将知识点不断的串联起来.这样才能得到更深层次的领悟.通过整理 ...

  5. iOS开发系列--音频播放(音效和音乐)播放本地的

    音频 在iOS中音频播放从形式上可以分为音效播放和音乐播放.前者主要指的是一些短音频播放,通常作为 点缀音频,对于这类音频不需要进行进度.循环等控制.后者指的是一些较长的音频,通常是主音频,对于这些音 ...

  6. c# 基于RTMP推流 PC+移动端 拉流播放

    网上关于直播相关的文章很多,但是讲解还是不够系统,对于刚刚接触直播开发的朋友实施起来会浪费不少时间.下面结合我自己的经验, 介绍一下直播方面的实战经验. 分成两个部分 第一部分是标题中介绍的基于RTM ...

  7. 使用Vitamio打造自己的Android万能播放器(6)——在线播放(播放列表)

    前言 新版本的VPlayer由设计转入开发阶段,预计开发周期为一个月,这也意味着新版本的Vitamio将随之发布,开发者们可以和本系列文章一样,先开发其他功能.本章内容为"在线视频播放列表& ...

  8. 使用Vitamio打造自己的Android万能播放器(7)——在线播放(下载视频)

    前言 本章将实现非常实用的功能——下载在线视频.涉及到多线程.线程更新UI等技术,还需思考产品的设计,如何将新加的功能更好的融入到现有的产品中,并不是简单的加一个界面就行了,欢迎大家交流产品设计和技术 ...

  9. Android 视频播放器 (一):使用VideoView播放视频

    一.简介 作为Android开发,我们不可避免的会接触到视频播放,VideoView做为最简单的播放器,我们是不应该不会的. 下面简单介绍一下VideoView: VideoView是使用MediaP ...

随机推荐

  1. BUUCTF-神秘龙卷风

    神秘龙卷风 通过提示知道压缩包密码是四位纯数字,通过爆破得到 得到一串编码 看样子应该是brainfuck编码 flag{e4bbef8bdf9743f8bf5b727a9f6332a8}

  2. 运行时应用自我保护(RASP):应用安全的自我修养

    应用程序已经成为网络黑客想要渗透到企业内部的绝佳目标. 因为他们知道如果能发现并利用应用程序的漏洞,他们就有超过三分之一的机会成功入侵. 更重要的是,发现应用程序漏洞的可能性也很大. Contrast ...

  3. 一篇文章带你深入浅出Vuex

    在写Vuex之前,我们先用一个简单的例子来实现一个小demo 大家都知道Vue的父传子用在很多场景,比如像这样: 父组件: <template> <div id="app& ...

  4. Python列表解析式的正确使用方式(一)

    先来逼逼两句: Python 是一种极其多样化和强大的编程语言!当需要解决一个问题时,它有着不同的方法.在本文中,将会展示列表解析式 (List Comprehension).我们将讨论如何使用它?什 ...

  5. ERROR: manifest for elasticsearch:latest not found: manifest unknown: manife

    当我们用docker下载 elasticsearch 的时候出现如下错误: 这里错误的原因是没有发现最新版,需要我们指定版本. docker pull elasticsearch:7.12.0 那我们 ...

  6. go-zero微服务实战系列(九、极致优化秒杀性能)

    上一篇文章中引入了消息队列对秒杀流量做削峰的处理,我们使用的是Kafka,看起来似乎工作的不错,但其实还是有很多隐患存在,如果这些隐患不优化处理掉,那么秒杀抢购活动开始后可能会出现消息堆积.消费延迟. ...

  7. 全国降雨侵蚀力因子R值

      数据下载链接:百度云下载链接​ 降雨侵蚀力因子其实是反应降雨对土壤侵蚀的潜在能力,就是降雨的冲刷对土壤的侵蚀效应. 在过去几天查阅文献资料的过程中,本人亲眼看见过的关于因子R的计算方法就超过30种 ...

  8. CSS基本知识点——带你走进CSS的新世界

    CSS基本知识点 我们在学习HTML之后,前端三件套第二件便是CSS,但CSS内容较多,我们分几部分讲解: (如果没有学习HTML,请参考之前文章:HTML知识点概括--一篇文章带你完全掌握HTML& ...

  9. labview从入门到出家9(进阶篇)--串口通讯

    ​ Labview在工控领域,如产线,实验室等环境用得较多,其中与仪器通讯控制的方式有串口(RS232,RS485,TTL),GPIB,网口,CAN等,其中串口在仪器还有单片机控制中用来调试居多.(很 ...

  10. 【我的面试-01】Web前端开发实习岗-面试题总结

    简单开头 首先技术面试官会根据简历里所写的项目和个人掌握技术栈提问(我不知道已经改过多少次简历了,因为前期投简历是真的是沉在茫茫大海,捞漂流瓶都捞不到的那种) 我的技术栈:(Vue还在苦苦的自学当中, ...