如何在IE浏览器播放RTSP或RTMP流

简介: 好多开发者一直苦恼于如何在IE浏览器环境下,构建低延迟的RTSP或RTMP播放,对于RTSP流来说,好多公司通常的做法是把RTSP转RTMP,然后分发到RTMP服务器,然后服务器转http-flv出来,浏览器直接播放http-flv流,亦或通过flash控件直接播放RTMP流,还有就是,转hls流出来,缺点是hls流延迟更大。

好多开发者一直苦恼于如何在IE浏览器环境下,构建低延迟的RTSP或RTMP播放,对于RTSP流来说,好多公司通常的做法是把RTSP转RTMP,然后分发到RTMP服务器,然后服务器转http-flv出来,浏览器直接播放http-flv流,亦或通过flash控件直接播放RTMP流,还有就是,转hls流出来,缺点是hls流延迟更大。


以上方案未尝不可,如果对播放体验和延迟要求更高,最简单的做法是直接在IE浏览器下加载activex控件。


大牛直播SDK(Github: https://github.com/daniulive/SmarterStreaming)在现有SDK的基础上,扩展了ocx控件,用于IE浏览器下的低延迟RTMP或RTSP播放,不谦虚的说,也可能是行业内功能支持和延迟最好的RTMP和RTSP播放器(支持RTMP/RTSP H.265(hevc)播放)。

页面展示

1. 功能齐全的单画面RTMP流或RTSP流播放:

20190321113028150.png

2. 同时播放4路RTMP流或RTSP流画面:

20190321113101148.png

本地播放和集成说明:

点我下载DEMO

本地播放

DEMO说明

  1. 1_player_ocx.html:单个窗口功能展示。
  2. 4_player_ocx.html:4窗口功能展示。
  3. SmartPlayer.exe:cs架构播放器。


运行网页播放端之前,请确保以管理员权限注册ocx控件:regplayerocx.bat右键-->“以管理员身份运行(A)”,同理,反注册也是需要管理员身份。

20190322180406102.png

注意:大牛直播RTSP/RTMP播放OCX控件只适用于微软IE浏览器。

对应封装接口

  ULONG NT_SetLogPath();
  ULONG NT_Open();
  ULONG NT_Close();
  ULONG NT_StartPlay();
  ULONG NT_StopPlay();
  ULONG NT_SetMute(LONG is_mute);
  ULONG NT_SetURL(LPCTSTR url);
  ULONG NT_SetBuffer(LONG buffer);
  ULONG NT_SetRTSPTcpMode(LONG isUsingTCP);
  ULONG NT_SetRtspTimeout(LONG timeout);
  ULONG NT_SetRtspAutoSwitchTcpUdp(LONG is_auto_switch_tcp_udp);
  ULONG NT_SetFastStartup(LONG isFastStartup);
  ULONG NT_SetLowLatencyMode(LONG mode);
  ULONG NT_SetFlipVertical(LONG is_flip);
  ULONG NT_SetFlipHorizontal(LONG is_flip);
  ULONG NT_SetRotation(LONG degress);
  ULONG NT_SwitchURL(LPCTSTR url);
  ULONG NT_SetCaptureImagePath(LPCTSTR path);
  ULONG NT_CaptureImage();
  ULONG NT_SetRecorderDirectory(LPCTSTR dir);
  ULONG NT_SetRecorderFileMaxSize(ULONG size);
  ULONG NT_NT_SP_RecorderFileNameRuler(ULONG type, LPCTSTR file_name_prefix, LONG append_date, LONG append_time);
  ULONG NT_SetRecorderAudioTranscodeAAC(LONG is_transcode);
  ULONG NT_SetRecorderVideo(LONG is_record_video);
  ULONG NT_SetRecorderAudio(LONG is_record_audio);
  ULONG NT_StartRecorder();
  ULONG NT_StopRecorder();
  ULONG NT_FullScreen();
  void OnSDKEventReceived(ULONG event_id, ULONG param1);
  void OnVideoSizeReceived(ULONG width, ULONG height);

设置LOG存放路径:

ULONG CSmartPlayerActiveXCtrl::NT_SetLogPath(LPCTSTR log_path)

请于NT_Open() 之前调用,代码示例:

var obj = document.getElementById("SmartPlayerActiveX");
//如需记录log文件,请确保log路径存在, 如多级目录, 可按照"D:\\Daniulive\\log"类似格式设定, 记录文件名: smart_sdk.log
obj.NT_SetLogPath("D:\\");

接口说明:

  1.  ULONG NT_Open();


打开player实例;

   2. ULONG NT_Close();


关闭player实例;

   3. ULONG NT_StartPlay();


开始播放;

   4. ULONG NT_StopPlay();


停止播放;

   5. ULONG NT_SetMute(LONG is_mute);


设置实时静音;

   6. ULONG NT_SetURL(LPCTSTR url);


设置播放的RTMP或RTSP url;

   7. ULONG NT_SetBuffer(LONG buffer);


设置buffer time,缓冲时间,单位:毫秒;

   8. ULONG NT_SetRTSPTcpMode(LONG isUsingTCP);


设置RTSP TCP/UDP播放模式;

   9. ULONG NT_SetRtspTimeout(LONG timeout);


设置RTSP超时时间;

   10. ULONG NT_SetRtspAutoSwitchTcpUdp(LONG is_auto_switch_tcp_udp);


设置是否自动切换TCP/UDP模式;

   11. ULONG NT_SetFastStartup(LONG isFastStartup);


设置是否快速启动;

   12. ULONG NT_SetLowLatencyMode(LONG mode);


设置是否低延迟模式播放;

   13. ULONG NT_SetFlipVertical(LONG is_flip);


设置垂直反转模式图像;

   14. ULONG NT_SetFlipHorizontal(LONG is_flip);


设置水平反转图像;

   15. ULONG NT_SetRotation(LONG degress);


设置旋转图像,可设定角度:0度 90度 180度 270度;

   16. ULONG NT_SwitchURL(LPCTSTR url);


设置快速切换RTSP/RTMP url;

   17. ULONG NT_SetCaptureImagePath(LPCTSTR path);


设置快照保存位置;

   18. ULONG NT_CaptureImage();


设置实时快照功能;

   19. ULONG NT_SetRecorderDirectory(LPCTSTR dir);


设置录像保存位置;

   20. ULONG NT_SetRecorderFileMaxSize(ULONG size);


设置单个录像文件最大size,单位:兆;

   21. ULONG NT_NT_SP_RecorderFileNameRuler(ULONG type, LPCTSTR file_name_prefix, LONG append_date, LONG append_time);


设置录像文件命名规则:是否需要前缀、是否添加日期、是否添加时间;

   22. ULONG NT_SetRecorderAudioTranscodeAAC(LONG is_transcode);


设置录像音频文件是否转AAC后录制,支持PCMA/PCMU/SPEEX转AAC后录制文件;

   23. ULONG NT_SetRecorderVideo(LONG is_record_video);


设置是否录制视频;

   24. ULONG NT_SetRecorderAudio(LONG is_record_audio);


设置是否录制音频;

   25. ULONG NT_StartRecorder();


开始录像;

   26. ULONG NT_StopRecorder();


停止录像;

   27. ULONG NT_FullScreen();


全屏显示窗口。

事件Event:  

1. void OnSDKEventReceived(ULONG event_id, ULONG param1);


回调网络状态、buffering状态、下载速度等;

事件类型:

<script>
  var NT_EVENT_ID_SMART_PLAYER_SDK = 0x01000000;
  var NT_SP_E_EVENT_ID_BASE = NT_EVENT_ID_SMART_PLAYER_SDK;
  var NT_SP_E_EVENT_ID_CONNECTING       = NT_SP_E_EVENT_ID_BASE | 0x2;  /*连接中*/
  var NT_SP_E_EVENT_ID_CONNECTION_FAILED    = NT_SP_E_EVENT_ID_BASE | 0x3;  /*连接失败*/
  var NT_SP_E_EVENT_ID_CONNECTED        = NT_SP_E_EVENT_ID_BASE | 0x4;  /*已连接*/
  var NT_SP_E_EVENT_ID_DISCONNECTED     = NT_SP_E_EVENT_ID_BASE | 0x5;  /*断开连接*/
  var NT_SP_E_EVENT_ID_NO_MEDIADATA_RECEIVED  = NT_SP_E_EVENT_ID_BASE | 0x8;  /*收不到RTMP数据*/
  var NT_SP_E_EVENT_ID_RTSP_STATUS_CODE       = NT_SP_E_EVENT_ID_BASE | 0xB;  /*rtsp status code上报, 目前只上报401, param1表示status code*/
  /* 接下来请从0x81开始*/
  var NT_SP_E_EVENT_ID_START_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x81; /*开始缓冲*/
  var NT_SP_E_EVENT_ID_BUFFERING     = NT_SP_E_EVENT_ID_BASE | 0x82; /*缓冲中, param1 表示百分比进度*/
  var NT_SP_E_EVENT_ID_STOP_BUFFERING  = NT_SP_E_EVENT_ID_BASE | 0x83; /*停止缓冲*/
  var NT_SP_E_EVENT_ID_DOWNLOAD_SPEED  = NT_SP_E_EVENT_ID_BASE | 0x91; /*下载速度, param1表示下载速度,单位是(Byte/s)*/
  var NT_SP_E_EVENT_ID_PLAYBACK_REACH_EOS   = NT_SP_E_EVENT_ID_BASE | 0xa1; /*播放结束, 直播流没有这个事件,点播流才有*/
  var NT_SP_E_EVENT_ID_RECORDER_REACH_EOS   = NT_SP_E_EVENT_ID_BASE | 0xa2; /*录像结束, 直播流没有这个事件, 点播流才有*/
  var NT_SP_E_EVENT_ID_PULLSTREAM_REACH_EOS   = NT_SP_E_EVENT_ID_BASE | 0xa3; /*拉流结束, 直播流没有这个事件,点播流才有*/
  var NT_SP_E_EVENT_ID_DURATION = NT_SP_E_EVENT_ID_BASE | 0xa8; /*视频时长,如果是直播,则不上报,如果是点播的话, 若能从视频源获取视频时长的话,则上报, param1表示视频时长,单位是毫秒(ms)*/
</script>

调用展示:

<script language='javascript' for="SmartPlayerActiveX"  event="OnSDKEventReceived(event_id, param1)">
    // Test 1 - statically load the script (This is the basis for the hack)
    // Works on IE8, IE9, IE10 and IE11
    var show_str = "";
    var connection_status = event_id;
    if (connection_status != 0)
    {
      show_str += "链接状态: ";
      if (NT_SP_E_EVENT_ID_CONNECTING == connection_status)
      {
        show_str += "链接中";
      }
      else if (NT_SP_E_EVENT_ID_CONNECTION_FAILED == connection_status)
      {
        show_str += "链接失败";
      }
      else if (NT_SP_E_EVENT_ID_CONNECTED == connection_status)
      {
        show_str += "链接成功";
      }
      else if (NT_SP_E_EVENT_ID_DISCONNECTED == connection_status)
      {
        show_str += "链接断开";
      }
      else if (NT_SP_E_EVENT_ID_NO_MEDIADATA_RECEIVED == connection_status)
      {
        show_str += "收不到数据";
      }
    }
    var download_speed = -1;
    if (NT_SP_E_EVENT_ID_DOWNLOAD_SPEED == event_id)
    {
      download_speed = param1;
    }
    if (download_speed != -1)
    {
      show_str += "下载速度:" + (download_speed * 8 / 1000).toFixed(0) + "kbps " + (download_speed / 1024).toFixed(0) + "KB/s";
    }
    var buffer_status = 0;
    if (NT_SP_E_EVENT_ID_START_BUFFERING == event_id
    || NT_SP_E_EVENT_ID_BUFFERING == event_id
    || NT_SP_E_EVENT_ID_STOP_BUFFERING == event_id)
    {
      buffer_status = event_id;
    }
    if (buffer_status != 0)
    {
      show_str += "缓冲状态: ";
      if (NT_SP_E_EVENT_ID_START_BUFFERING == buffer_status)
      {
        show_str += "开始缓冲";
      }
      else if (NT_SP_E_EVENT_ID_BUFFERING == buffer_status)
      {
        show_str += "缓冲中" + param1 + "%";
      }
      else if (NT_SP_E_EVENT_ID_STOP_BUFFERING == buffer_status)
      {
        show_str += "结束缓冲";
      }
    }
    var EventMsgText = document.getElementById("EventMsg");
    EventMsgText.innerHTML = show_str;
  </script>

2. void OnVideoSizeReceived(ULONG width, ULONG height);


回调视频宽高信息。


调用展示:

<script language='javascript' for="SmartPlayerActiveX"  event="OnVideoSizeReceived(width, height)">
  // Test 1 - statically load the script (This is the basis for the hack)
  // Works on IE8, IE9, IE10 and IE11
  var VideoResolutionText = document.getElementById("VideoResolution");
  VideoResolutionText.innerHTML = width + "*" + height;
</script>

SDK接口调用实例:

播放和录像调用示例:

var is_player_opened = false;
var is_playing = false;
var is_recording = false;
function OpenPlayer()
{        
  if(is_player_opened)
  {
    return;
  }
  var obj = document.getElementById("SmartPlayerActiveX");
  //如需记录log文件,请确保log路径存在, 如多级目录, 可按照"D:\\Daniulive\\log"类似格式设定, 记录文件名: smart_sdk.log
  obj.NT_SetLogPath("D:\\");
  var ret = obj.NT_Open();
  if(ret == 0)
  {   
    //设置TCP/UDP模式
    var rtsp_tcp_mode = document.getElementById("rtspTcpMode").checked ? 1 : 0;
    obj.NT_SetRTSPTcpMode(rtsp_tcp_mode);
    //设置RTSP超时时间
    var rtsp_timeout = document.getElementById("rtspTimeout").value;
    obj.NT_SetRtspTimeout(rtsp_timeout);
    //设置是否自动切换TCP-UDP模式
    var rtsp_auto_switch_tcp_udp = document.getElementById("rtspAutoSwitchTcpUdp").checked ? 1 : 0;
    obj.NT_SetRtspAutoSwitchTcpUdp(rtsp_auto_switch_tcp_udp);
    //设置是否快速启动
    var fast_startup_mode = document.getElementById("fastStartupMode").checked ? 1 : 0;
    obj.NT_SetFastStartup(fast_startup_mode);
    //设置需要播放或录像的RTSP/RTMP url
    var url = document.getElementById("playorReocordUrl").value;
    obj.NT_SetURL(url);
    //设置实时截图路径(可自行设置或选取系统存在的文件夹), 如多级目录可按照"D:\\Daniulive\\image"类似格式设定
    //var image_path = "D:\\";
    obj.NT_SetCaptureImagePath(image_path);
    is_player_opened = true;
  }
}
function ClosePlayer()
{
  if(is_player_opened)
  {
    var obj = document.getElementById("SmartPlayerActiveX");
    obj.NT_Close();
    var EventMsgText = document.getElementById("EventMsg"); 
    EventMsgText.innerHTML = "";
    is_player_opened = false;
  }
}
function OnBnClickedPlay()
{
  if(!isIE())
  {
    alert("非IE浏览器,请用IE打开播放控件..");
    return;
  }
  if(!isActiveXInstalled())
  {
    alert("控件未加载,请先加载控件..");
    return;
  }
  if(is_playing)
  {
    StopPlayback();
  }
  else
  {
    StartPlayback();
  }
}
//开始播放
function StartPlayback() {
  if(!is_playing && !is_recording)
  {
    OpenPlayer();
  }
  var obj = document.getElementById("SmartPlayerActiveX");
  //设置是否启用低延迟模式
  var low_latency_mode = document.getElementById("lowlatencyMode").checked ? 1 : 0;
  obj.NT_SetLowLatencyMode(low_latency_mode);
  //设置缓冲时间
  var buffer_time = document.getElementById("bufferTime").value;
  obj.NT_SetBuffer(buffer_time);
  var ret = obj.NT_StartPlay();
  if(ret == 0)
  {
    is_playing = true;  
    var playBtnText = document.getElementById("playBtn");
    playBtnText.innerHTML = "停止播放";
  }   
}
//停止播放
function StopPlayback() {
  if(!is_playing)
  {
    return;
  }
  var obj = document.getElementById("SmartPlayerActiveX");
  obj.NT_StopPlay();
  is_playing = false;
  var playBtnText = document.getElementById("playBtn");
  playBtnText.innerHTML = "开始播放";
  if(!is_recording)
  {
    ClosePlayer();
  }
  var VideoResolutionText = document.getElementById("VideoResolution");
  VideoResolutionText.innerHTML = "";
}
function OnBnClickedRecord()
{
  if(!isIE())
  {
    alert("非IE浏览器,请用IE打开播放控件..");
    return;
  }
  if(!isActiveXInstalled())
  {
    alert("控件未加载,请先加载控件..");
    return;
  }
  if(is_recording)
  {
    StopRecorder();
  }
  else
  {
    StartRecorder();
  }
}
//开始录像
function StartRecorder() {
  if(!is_playing && !is_recording)
  {
    OpenPlayer();
  }
  var obj = document.getElementById("SmartPlayerActiveX");
  //设置实时录像存放路径(可自行设置或选取系统存在的文件夹), 如多级目录可按照"D:\\Daniulive\\rec"类似格式设定
  var rec_dir = "D:\\";
  obj.NT_SetRecorderDirectory(rec_dir);
  var rec_max_size = 200;
  obj.NT_SetRecorderFileMaxSize(rec_max_size);
  var type = 0;
  var file_name_prefix = "daniulive";
  var append_date = 1;
  var append_time = 1;
  obj.NT_NT_SP_RecorderFileNameRuler(type, file_name_prefix, append_date, append_time);
  var is_transcode = 1;
  obj.NT_SetRecorderAudioTranscodeAAC(is_transcode);
  var is_record_video = 1;
  obj.NT_SetRecorderVideo(is_record_video);
  var is_record_audio = 1;
  obj.NT_SetRecorderAudio(is_record_audio);
  var ret = obj.NT_StartRecorder();
  if(ret == 0)
  {
    is_recording = true;
    var recordBtnText = document.getElementById("recordBtn");
    recordBtnText.innerHTML = "停止录像";
  }
}
//停止录像
function StopRecorder() {
  if(!is_recording)
  {
    return;
  }
  var obj = document.getElementById("SmartPlayerActiveX");
  obj.NT_StopRecorder();
  is_recording = false;
  var recordBtnText = document.getElementById("recordBtn");
  recordBtnText.innerHTML = "开始录像";
  if(!is_playing)
  {
    ClosePlayer();
  }
}

快速切换URL调用示例:

//快速切换播放URL
function SwitchUrl() {
  if(!is_playing)
  {
    return;
  }
  var obj = document.getElementById("SmartPlayerActiveX");
  var switch_url = document.getElementById("playorReocordUrl").value;
  obj.NT_SwitchURL(switch_url);
}

实时静音调用示例:

//实时静音
var is_mute = 1;  
function SetMute() {
  var obj = document.getElementById("SmartPlayerActiveX");
  obj.NT_SetMute(is_mute);
  var muteText = document.getElementById("MuteBtn");
  if(is_mute == 1 )
  {
    is_mute = 0;
    muteText.innerHTML = "取消静音";
  }
  else
  {
    is_mute = 1;
    muteText.innerHTML  = "实时静音";
  }
}

视频view垂直反转、水平反转、旋转调用示例:

//垂直反转
var is_flip_vertical = 1;
function SetFlipVertical() {
  var obj = document.getElementById("SmartPlayerActiveX");
  obj.NT_SetFlipVertical(is_flip_vertical);
  var flipVerticalText = document.getElementById("FlipVerticalBtn");
  if(is_flip_vertical == 1 )
  {
    is_flip_vertical = 0;
    flipVerticalText.innerHTML = "取消反转";
  }
  else
  {
    is_flip_vertical = 1;
    flipVerticalText.innerHTML  = "垂直反转";
  }
}
//水平反转
var is_flip_horizontal = 1;
function SetFlipHorizontal() {
  var obj = document.getElementById("SmartPlayerActiveX");
  obj.NT_SetFlipHorizontal(is_flip_horizontal);
  var flipHorizontalText = document.getElementById("FlipHorizontalBtn");
  if(is_flip_horizontal == 1 )
  {
    is_flip_horizontal = 0;
    flipHorizontalText.innerHTML = "取消反转";
  }
  else
  {
    is_flip_horizontal = 1;
    flipHorizontalText.innerHTML  = "水平反转";
  }
}
//视频view旋转
var rotate_degrees_ = 0;
function SetRotation() {
  rotate_degrees_ += 90;
  rotate_degrees_ = rotate_degrees_ % 360;
  var obj = document.getElementById("SmartPlayerActiveX");
  obj.NT_SetRotation(rotate_degrees_);
  var rotateText = document.getElementById("RotateBtn");
  if (0 == rotate_degrees_)
  {
    rotateText.innerHTML = "旋转90度";
  }
  else if (90 == rotate_degrees_)
  {
    rotateText.innerHTML = "旋转180度";
  }
  else if (180 == rotate_degrees_)
  {
    rotateText.innerHTML = "旋转270度";
  }
  else if (270 == rotate_degrees_)
  {
    rotateText.innerHTML = "不旋转";
  }
}

实时截图调用示例:

function CaptureImage() {
  var obj = document.getElementById("SmartPlayerActiveX");
  obj.NT_CaptureImage();
}

全屏显示窗口调用示例:

//全屏显示窗口
function FullScreen() {
  var obj = document.getElementById("SmartPlayerActiveX");
  obj.NT_FullScreen();
}


相关文章
|
4天前
解决win10无法打开自带的IE浏览器的问题
解决win10无法打开自带的IE浏览器的问题
18 0
|
2月前
|
存储 机器人
在阿里云RPA中,你可以通过以下步骤来更改默认唤醒IE浏览器的地址
【2月更文挑战第28天】在阿里云RPA中,你可以通过以下步骤来更改默认唤醒IE浏览器的地址
21 1
|
2月前
|
JavaScript IDE 测试技术
Rtsp转Flv在浏览器中播放
【2月更文挑战第5天】本文简单介绍如何间接实现在浏览器中播放rtsp的流,涉及技术点和工具较多,本文仅做功能实现思路的梳理和简单的代码实践,后续整理更深入的实现原理。
103 1
|
5月前
|
Web App开发 JavaScript 前端开发
JavaScript在IE和标准浏览器下的兼容性处理
JavaScript在IE和标准浏览器下的兼容性处理
42 0
|
6月前
|
前端开发
border-radius 兼容 IE8浏览器
border-radius 兼容 IE8浏览器
42 1
|
6月前
|
Web App开发 移动开发 安全
IE浏览器,和Edge浏览器
IE浏览器,和Edge浏览器
|
6月前
|
JavaScript
兼容IE浏览器
兼容IE浏览器
33 0
|
7月前
|
编解码 Cloud Native 前端开发
H.265 视频在浏览器中的播放问题探究
H.265 视频在浏览器中的播放问题探究
102 0
|
7月前
|
Web App开发 前端开发 JavaScript
|
8月前
|
Web App开发 XML 编解码
IE浏览器下载文件中文文件名乱码问题解决
IE浏览器下载文件中文文件名乱码问题解决
85 0