Wowza 中的冗余 HLS 流
Redundant HLS Streams in Wowza
当使用 Java API 生成动态播放列表 (AMLST) 时,是否可以将备用(备份)流添加到 Wowza 中的 HLS 清单。
我有一个这样的代码,我在其中动态添加不同的比特率,但我想添加一个备份流。 (我尝试添加第二个 MediaListSegment 但它似乎不起作用)。
package com.wowza.wms.plugin.test.module;
import com.wowza.wms.medialist.*;
import com.wowza.wms.module.*;
import com.wowza.wms.stream.*;
import com.wowza.wms.application.*;
public class ModuleAMLSTTestLive extends ModuleBase
{
class MyMediaListProvider implements IMediaListProvider
{
public MediaList resolveMediaList(IMediaListReader mediaListReader, IMediaStream stream, String streamName)
{
MediaList mediaList = new MediaList();
MediaListSegment segment = new MediaListSegment();
mediaList.addSegment(segment);
MediaListRendition rendition1 = new MediaListRendition();
segment.addRendition(rendition1);
rendition1.setName(streamName+"_400");
rendition1.setBitrateAudio(128000);
rendition1.setBitrateVideo(400000);
rendition1.setWidth(320);
rendition1.setHeight(240);
rendition1.setAudioCodecId("mp4a.40.2");
rendition1.setVideoCodecId("avc1.66.12");
MediaListRendition rendition2 = new MediaListRendition();
segment.addRendition(rendition2);
rendition2.setName(streamName+"_800");
rendition2.setBitrateAudio(128000);
rendition2.setBitrateVideo(800000);
rendition2.setWidth(640);
rendition2.setHeight(480);
rendition2.setAudioCodecId("mp4a.40.2");
rendition2.setVideoCodecId("avc1.77.31");
return mediaList;
}
}
public void onAppStart(IApplicationInstance appInstance)
{
appInstance.setMediaListProvider(new MyMediaListProvider());
}
}
虽然API不支持这个,但我终于找到了解决办法:
可以通过在 URI 或 DOMAIN cupertino 标记中使用流的绝对路径指定流来定义主流和备用流。
微笑样本:
<body>
<switch>
<video src="mp4:foo.mp4" system-bitrate="300000">
<param name="videoCodecId" value="avc1.66.30" valuetype="data"/>
<param name="audioCodecId" value="mp4a.40.2" valuetype="data"/>
<param name="cupertinoTag.URI" value="http://serverwowza1.foo.com:1935/vod/mp4:foo.mp4/chunklist.m3u8" valuetype="data"/>
</video>
<video src="mp4:foo.mp4" system-bitrate="300000" >
<param name="videoCodecId" value="avc1.66.30" valuetype="data"/>
<param name="audioCodecId" value="mp4a.40.2" valuetype="data"/>
<param name="cupertinoTag.URI" value="http://serverwowza2.foo.com:1935/vod/mp4:sample.mp4/chunklist.m3u8" valuetype="data"/>
</video>
...
您的解决方案有一个重大问题,您的组块列表 URI 不包含 Wowza 会话 ID(“_w#### #" 通常在 chunklist 文件名中),它真的不能,因为你在创建 smil 文件时不可能知道那是什么。如果没有 session id 那么每个玩家对该块列表的每个请求都会创建一个新的 "Wowza HTTP session",这可能会导致一些问题随着时间的推移,Java 堆消耗和无法跟踪连接的实际客户端数量。
更好的(尽管未记录)解决方案是将您的两个条目替换为一个条目,该条目指定一个 "cupertinoTag.DOMAIN" 参数和您的两个域:
<video src="mp4:foo.mp4" system-bitrate="300000">
<param name="videoCodecId" value="avc1.66.30" valuetype="data"/>
<param name="audioCodecId" value="mp4a.40.2" valuetype="data"/>
<param name="cupertinoTag.DOMAIN" value="serverwowza1.foo.com:1935,serverwowza2.foo.com:1935" valuetype="data"/>
</video>
然后它应该在生成的主播放列表中创建两个 fully-formed 绝对块列表条目(EXT-X-STREAM-INF 标签后跟它们的关联 URI),每个域一个,包括 session id.
请注意,具有指定 id 的会话将在首次请求块列表(来自同一玩家)时创建备份服务器。
对于 amlst API,您实际上可以通过再现 properties 成员来做同样的事情。
rendition.getProperties().setProperty("cupertinoTag.DOMAIN", "serverwowza1.foo.com:1935,serverwowza2.foo.com:1935");
当使用 Java API 生成动态播放列表 (AMLST) 时,是否可以将备用(备份)流添加到 Wowza 中的 HLS 清单。
我有一个这样的代码,我在其中动态添加不同的比特率,但我想添加一个备份流。 (我尝试添加第二个 MediaListSegment 但它似乎不起作用)。
package com.wowza.wms.plugin.test.module;
import com.wowza.wms.medialist.*;
import com.wowza.wms.module.*;
import com.wowza.wms.stream.*;
import com.wowza.wms.application.*;
public class ModuleAMLSTTestLive extends ModuleBase
{
class MyMediaListProvider implements IMediaListProvider
{
public MediaList resolveMediaList(IMediaListReader mediaListReader, IMediaStream stream, String streamName)
{
MediaList mediaList = new MediaList();
MediaListSegment segment = new MediaListSegment();
mediaList.addSegment(segment);
MediaListRendition rendition1 = new MediaListRendition();
segment.addRendition(rendition1);
rendition1.setName(streamName+"_400");
rendition1.setBitrateAudio(128000);
rendition1.setBitrateVideo(400000);
rendition1.setWidth(320);
rendition1.setHeight(240);
rendition1.setAudioCodecId("mp4a.40.2");
rendition1.setVideoCodecId("avc1.66.12");
MediaListRendition rendition2 = new MediaListRendition();
segment.addRendition(rendition2);
rendition2.setName(streamName+"_800");
rendition2.setBitrateAudio(128000);
rendition2.setBitrateVideo(800000);
rendition2.setWidth(640);
rendition2.setHeight(480);
rendition2.setAudioCodecId("mp4a.40.2");
rendition2.setVideoCodecId("avc1.77.31");
return mediaList;
}
}
public void onAppStart(IApplicationInstance appInstance)
{
appInstance.setMediaListProvider(new MyMediaListProvider());
}
}
虽然API不支持这个,但我终于找到了解决办法:
可以通过在 URI 或 DOMAIN cupertino 标记中使用流的绝对路径指定流来定义主流和备用流。
微笑样本:
<body>
<switch>
<video src="mp4:foo.mp4" system-bitrate="300000">
<param name="videoCodecId" value="avc1.66.30" valuetype="data"/>
<param name="audioCodecId" value="mp4a.40.2" valuetype="data"/>
<param name="cupertinoTag.URI" value="http://serverwowza1.foo.com:1935/vod/mp4:foo.mp4/chunklist.m3u8" valuetype="data"/>
</video>
<video src="mp4:foo.mp4" system-bitrate="300000" >
<param name="videoCodecId" value="avc1.66.30" valuetype="data"/>
<param name="audioCodecId" value="mp4a.40.2" valuetype="data"/>
<param name="cupertinoTag.URI" value="http://serverwowza2.foo.com:1935/vod/mp4:sample.mp4/chunklist.m3u8" valuetype="data"/>
</video>
...
您的解决方案有一个重大问题,您的组块列表 URI 不包含 Wowza 会话 ID(“_w#### #" 通常在 chunklist 文件名中),它真的不能,因为你在创建 smil 文件时不可能知道那是什么。如果没有 session id 那么每个玩家对该块列表的每个请求都会创建一个新的 "Wowza HTTP session",这可能会导致一些问题随着时间的推移,Java 堆消耗和无法跟踪连接的实际客户端数量。
更好的(尽管未记录)解决方案是将您的两个条目替换为一个条目,该条目指定一个 "cupertinoTag.DOMAIN" 参数和您的两个域:
<video src="mp4:foo.mp4" system-bitrate="300000">
<param name="videoCodecId" value="avc1.66.30" valuetype="data"/>
<param name="audioCodecId" value="mp4a.40.2" valuetype="data"/>
<param name="cupertinoTag.DOMAIN" value="serverwowza1.foo.com:1935,serverwowza2.foo.com:1935" valuetype="data"/>
</video>
然后它应该在生成的主播放列表中创建两个 fully-formed 绝对块列表条目(EXT-X-STREAM-INF 标签后跟它们的关联 URI),每个域一个,包括 session id.
请注意,具有指定 id 的会话将在首次请求块列表(来自同一玩家)时创建备份服务器。
对于 amlst API,您实际上可以通过再现 properties 成员来做同样的事情。
rendition.getProperties().setProperty("cupertinoTag.DOMAIN", "serverwowza1.foo.com:1935,serverwowza2.foo.com:1935");