1. 程式人生 > >如何在IE瀏覽器播放RTSP或RTMP流(RTSP/RTMP OCX控件)

如何在IE瀏覽器播放RTSP或RTMP流(RTSP/RTMP OCX控件)

sha click director 測試 tmp 下載速度 資料 nvi 亦或

好多開發者一直苦惱於如何在IE瀏覽器環境下,構建低延遲的RTSP或RTMP播放,對於RTSP流來說,好多公司通常的做法是把RTSP轉RTMP,然後分發到RTMP服務器,然後服務器轉http-flv出來,瀏覽器直接播放http-flv流,亦或通過flash控件直接播放RTMP流,還有就是,轉hls流出來,缺點是hls流延遲更大。

以上方案未嘗不可,如果對播放體驗和延遲要求更高,最簡單的做法是直接在IE瀏覽器下加載activex控件,擴展了ocx控件,用於IE瀏覽器下的低延遲RTMP或RTSP播放。

頁面展示

  1. 功能齊全的單畫面RTMP流或RTSP流播放:
    技術分享圖片

  2. 同時播放4路RTMP流或RTSP流畫面:

技術分享圖片

本地播放和集成說明:

點我下載DEMO請添加鏈接描述

本地播放

DEMO說明
1_player_ocx.html:單個窗口功能展示。
4_player_ocx.html:4窗口功能展示。
SmartPlayer.exe:cs架構播放器。
運行網頁播放端之前,請確保以管理員權限註冊ocx控件:regplayerocx.bat右鍵-->“以管理員身份運行(A)”,同理,反註冊也是需要管理員身份。
技術分享圖片

註意:大牛直播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>
  1. 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();
}

相關資料和測試控件下載:
Github:?https://github.com/daniulive/SmarterStreaming

如何在IE瀏覽器播放RTSP或RTMP流(RTSP/RTMP OCX控件)