当前您所在的位置:首页>新闻中心>新品发布
新品发布
行业动态
营销活动

Wowza技术:如何使用Wowza nDVR API 来检查DVR的流录制?

发布时间:2021/01/03 浏览量:2214

这篇文章通过一个HTTPProvider展示了如何使用Wowza nDVR API 来检查DVR的流录制,这个API使用dvrTimepacketTime UTC time 三类时间来查询。 

注意:这个功能需要Wowza Media Server® 3.0.3.12及以上版本的支持。

 


时间单位 
每一个nDVR 的切片的时间有三类时间单位


主要的接口 
每一个IDvrStreamStore 包含一个IDvrManifest它代表了DVR录制流的组成信息。 

IDvrManifest 包含几个通道的信息,包括音频和视频通道。这个class DvrChannelManifest。这些通道由多个manifest记录组成,它包含了分别用三个时间单位表示的一个时间戳。 

通过从IApplicationInstance 定位到音频和视频流,我们可以检测到第一条和最后一条记录信息,并确定3个时间单位的开始和结束的时间。 

HTTP Provider的例子 
下面的例子用 HTTPProvider 机制展示了如何查询一个流的所有相关DVR录制信息。 这个例子展示了DVR录制是否正在进行、是否包含音频或视频,并报告DVR的开始和结束时间、数据包和UTC时间标。 

这里提供的代码只是一个示例,你可以很容易修改它以适应你的需求。 

HTTPProviderwowza media server的扩展,它可以监听来自[install-dir]/conf/VHost.xml中的定义的HostPort上的HTTP请求,你可以通过URL请求来控制它。 在用户使用指南的对应章节可以获得更多细节信息。 


使用Wowza IDE将这个class编译为一个jar文件,并将其拷贝到[install-dir]/lib文件夹下。 然后将这个HTTPProvider添加到/conf/VHost.xml /HostPort (Port 8086)/HTTPProviders里面。这个HTTPProvider应该被添加到ServiceVersion HTTPProvider上面。在用户使用指南上详细解释了如何开发和部署HTTPProvider 

Code:

 

         com.wowza.wms.plugin.test.dvr.api.HTTPDvrStreamQuery

         dvrstreamquery*

         none

 

 

         com.wowza.wms.http.HTTPServerVersion

         *

         none

 


使用HTTP Provider 
nDVR的录制,可以通过URL来访问HTTPProvider的方式来进行控制。格式如下

Code:

http://[wowza-ip-address]:8086/dvrstreamquery?action=query&app=[application-name]&streamname=[stream-name][&forceload=true]

其中:


这个HTTP Provider将想浏览器返回一个HTML响应,如下

Code:

query myStream:

 

Store:myStream.0

isLive: false hasAudio: true hasVideo: true

dvrStart: 0.000 dvrEnd: 48.466 duration:48.466

packetStart: 0 packetEnd: 48466

utcStart: 2011-Dec-20 14:37:20 utcEnd:2011-Dec-20 14:38:08

 

Store:myStream.1

isLive: true hasAudio: true hasVideo: true

dvrStart: 0.000 dvrEnd: 1.648 duration:1.648

packetStart: 1449298 packetEnd: 1450946

utcStart: 2012-Jan-03 17:06:06 utcEnd:2012-Jan-03 17:06:07


代理示例 

下面是一个查询DVR存储信息的代码示例

Code:

package com.wowza.wms.plugin.test.dvr.api;

 

import java.io.OutputStream;

import java.text.SimpleDateFormat;

import java.util.*;

 

import com.wowza.wms.application.IApplicationInstance;

import com.wowza.wms.dvr.*;

import com.wowza.wms.http.*;

importcom.wowza.wms.logging.WMSLoggerFactory;

importcom.wowza.wms.plugin.test.dvr.api.HTTPDvrStreamQuery.StartEndTimes;

import com.wowza.wms.stream.mediacaster.MediaStreamMediaCasterUtils;

import com.wowza.wms.vhost.*;

 

// Usage: http://[wowza-ip-address]:8086/dvrstreamquery?action=query&app=[application-name]&streamname=[stream-name][&forceload=true]

public class HTTPDvrStreamQuery extendsHTTProvider2Base {

   private static final String CLASSNAME = "HTTPDvrStreamQuery";

   private static final Class.class;   

 

   public void onHTTPRequest(IVHost vhost, IHTTPRequest req, IHTTPResponseresp) {

       if (!doHTTPAuthentication(vhost, req, resp)) {

           return;

       }

 

        WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME+ " HTTPRequest");

 

       Map> params = req.getParameterMap();

 

       String action = "";

       String app = "";

       String streamName = "";

       String report = "";

        boolean forceLoad = false;

 

       if (req.getMethod().equalsIgnoreCase("get") ||req.getMethod().equalsIgnoreCase("post")) {

           req.parseBodyForParams(true);

 

           try {

                if(params.containsKey("action")) {

                   action =params.get("action").get(0);

                } else {

                    report +="
" + "action" + " is required";

                }

               WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME + " action: "+ action);

 

                if(params.containsKey("app")) {

                    app =params.get("app").get(0);

                } else {

                    report +="
" + "app" + " is required";

                }

               WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME + " app: " +app);

 

                if(params.containsKey("streamname")) {

                    streamName =params.get("streamname").get(0);

               } else {

                    report +="
" + "streamname" + " is required";

                }

               WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME + " streamName:" + streamName);

               

                if (params.containsKey("forceload")){

                    String forceLoadString =params.get("forceload").get(0);

                    forceLoad =Boolean.parseBoolean(forceLoadString);

                   WMSLoggerFactory.getLogger(CLASS).info(CLASSNAME + " forceload:" + forceLoadString);

                }

               

           } catch (Exception ex) {

                report = "Error: " +ex.getMessage();

           }

       } else {

           report = "Nothing to do.";

       }

 

       try {

           IApplicationInstance appInstance =vhost.getApplication(app).getAppInstance("_definst_");

           

           // If no error

           if (report.equalsIgnoreCase("")) {

                if(action.equalsIgnoreCase("query")) {

                   WMSLoggerFactory.getLogger(CLASS).info(String.format("%s.%s:%s", CLASSNAME, "query", streamName));

 

                    String streamTypeStr =appInstance.getStreamType();

 

                    boolean isLiveRepeaterEdge= false;

                    while (true) {

                        StreamList streamDefs =appInstance.getVHost().getStreamTypes();

                        StreamItem streamDef =streamDefs.getStreamDef(streamTypeStr);

                        if (streamDef == null)

                            break;

                        isLiveRepeaterEdge =streamDef.getProperties().getPropertyBoolean("isLiveRepeaterEdge",isLiveRepeaterEdge);

                        break;

                    }

 

                    if (isLiveRepeaterEdge)

                        streamName =MediaStreamMediaCasterUtils.mapMediaCasterName(appInstance, null, streamName);

 

                        String result =queryDvrStreamInfo(appInstance, streamName, forceLoad);

                        report = action +" " + streamName + ":";

                        report = report +"

\n" + result;

 

                } else {

                    report = "Action:"+action + " is not valid.";

                }

           }

 

       } catch (Exception e) {

           report = "Error: " + e.getMessage();

       }

 

       String retStr = "

 

" + report+ "

";

 

 

       try {

           OutputStream out = resp.getOutputStream();

           byte[] outBytes = retStr.getBytes();

           out.write(outBytes);

       } catch (Exception e) {

           WMSLoggerFactory.getLogger(CLASS).error(CLASSNAME + ": " +e.toString());

       }

 

    }

 

 

   public String queryDvrStreamInfo(IApplicationInstance appInstance,String streamName, boolean forceLoad) {

 

       StringBuffer sb = new StringBuffer();

 

       IDvrStreamManager dvrMgr =DvrStreamManagerUtils.getStreamManager(appInstance, IDvrConstants.DVR_STREAMING_PACKETIZER_ID,streamName, forceLoad);

 

       if (dvrMgr == null) {

           sb.append("Stream "+streamName+" not loaded.");

       } else {

           List stores = dvrMgr.getStreamStores();

           for (IDvrStreamStore store : stores) {

               sb.append(queryDvrStoreInfo(store));

           }

       }

       return sb.toString();           

    }

 

   public String queryDvrStoreInfo(IDvrStreamStore store) {

 

       StringBuffer sb = new StringBuffer();

       if (store != null) {

 

           boolean hasAudio = store.hasAudio();

           boolean hasVideo = store.hasVideo();

           boolean isLive = store.isLive();

 

           sb.append(String.format("
Store:%s",store.getStreamName()));

 

           String result = String.format("
  isLive: %s  hasAudio: %s   hasVideo: %s",isLive, hasAudio, hasVideo);

           sb.append(result);

 

           long duration = -1;

 

           StartEndTimes dvrTimes = queryDvrStartStop(store);

           if (dvrTimes != null) {

                duration = dvrTimes.end -dvrTimes.start;

                String s =String.format("
dvrStart: %s dvrEnd: %s  duration: %s",formatDvrTime(dvrTimes.start), formatDvrTime(dvrTimes.end),formatDvrTime(duration));

                sb.append(s);

           }

 

           StartEndTimes packetTimes = queryPacketStartStop(store);

           if (packetTimes != null) {

                String s =String.format("
packetStart: %s packetEnd: %s", formatPacketTime(packetTimes.start),formatPacketTime(packetTimes.end));

                sb.append(s);

            }

 

           StartEndTimes utcTimes = queryUtcStartStop(store);

           if (utcTimes != null) {

                String s =String.format("
utcStart: %s utcEnd: %s", formatUtcTime(utcTimes.start),formatUtcTime(utcTimes.end));

               sb.append(s);           

           }

 

           sb.append("

");

       }

       return sb.toString();           

    }

 

 

 

   protected StartEndTimes queryDvrStartStop(IDvrStreamStore store) {

       if (store == null) {

           return null;

       }

       DvrChannelManifest manifest = getVideoOrAudioManifest(store);

 

       if (manifest == null) {

           return null;

       }

 

       DvrManifestEntry firstEntry = manifest.getFirstEntry();

       DvrManifestEntry lastEntry = manifest.getLastRecordedEntry();

 

       long start = firstEntry.getStartTimecode();

       long end = lastEntry.getStopTimecode();

 

       return new StartEndTimes(start, end);

    }

 

   protected StartEndTimes queryPacketStartStop(IDvrStreamStore store) {

       if (store == null) {

           return null;

       }

       DvrChannelManifest manifest = getVideoOrAudioManifest(store);

 

       if (manifest == null) {

           return null;

       }

 

       DvrManifestEntry firstEntry = manifest.getFirstEntry();

       DvrManifestEntry lastEntry = manifest.getLastRecordedEntry();

 

       long start = firstEntry.getPacketStartTime();

       long end = lastEntry.getPacketStartTime() + lastEntry.getDuration();

 

       return new StartEndTimes(start, end);

    }

   

   protected StartEndTimes queryUtcStartStop(IDvrStreamStore store) {

       if (store == null) {

           return null;

       }

       DvrChannelManifest manifest = getVideoOrAudioManifest(store);

 

       if (manifest == null) {

           return null;

       }

 

       DvrManifestEntry firstEntry = manifest.getFirstEntry();

       DvrManifestEntry lastEntry = manifest.getLastRecordedEntry();

 

       long start = firstEntry.getUtcStartTime();

       long end = lastEntry.getUtcStartTime() + lastEntry.getDuration();

 

       return new StartEndTimes(start, end);

    }

 

   private DvrChannelManifest getVideoOrAudioManifest(IDvrStreamStorestore) {

       IDvrManifest manifest = store.getManifest();

 

       boolean hasAudio = store.hasAudio();

        boolean hasVideo = store.hasVideo();

 

       DvrChannelManifest channelManifest = null;

 

       if (hasVideo) {

           channelManifest = manifest.getManifestChannel(IVHost.CONTENTTYPE_VIDEO);

       } else if (hasAudio) {

           channelManifest = manifest.getManifestChannel(IVHost.CONTENTTYPE_AUDIO);

       }

       return channelManifest;

    }

 

   

    protected String formatUtcTime(long utc) {

     final String UTC_FORMAT = "yyyy-MMM-dd HH:mm:ss";

 

     SimpleDateFormat dateFormatLocal = new SimpleDateFormat(UTC_FORMAT);

 

     return dateFormatLocal.format(new Date(utc));

    }

   

   protected String formatDvrTime(long t) {

       return String.format("%.3f", t/1000.0);

    }

 

   protected String formatPacketTime(long t) {

       return String.format("%s", t);

    }

   

 

   public class StartEndTimes {

       long start = -1;

       long end = -1;

 

       public StartEndTimes(long start, long end) {

           this.start = start;

           this.end = end;

       }

    }

 

   

}

 

Wowza Streaming Engine 4是业界功能强大、API接口丰富的流媒体Server产品,采用它作为流媒体服务器产品的案例很多,直播、在线教育、IPTV都有它的用武之地。

北京哲想软件有限公司