ios - Google ChromeCast 从 iOS 播放 m3u8

标签 ios video chromecast google-cast m3u8

我想知道如何从我的 iOS 应用程序发送来自 m3u8 URL 的视频,以便通过 Google ChromeCast 在我的电视上播放。播放列表包含一堆“ts”网址。现在我有:

- (void)deviceManager:(GCKDeviceManager *)deviceManager
didConnectToCastApplication:(GCKApplicationMetadata *)applicationMetadata
                  sessionID:(NSString *)sessionID
        launchedApplication:(BOOL)launchedApp
{

  _gcChannel                   = [[GCKMediaControlChannel alloc] init];
  _gcChannel.delegate          = self;
  [deviceManager    addChannel: _gcChannel];
  GCKMediaMetadata *metadata   = [[GCKMediaMetadata alloc] init];
  NSTimeInterval    startTime  = 0;
  [metadata setString:@"Stream it" forKey:kGCKMetadataKeyTitle];

  GCKMediaInformation *mediaInformation = [[GCKMediaInformation alloc] initWithContentID:URLTOM3U8 streamType:GCKMediaStreamTypeUnknown contentType:@"video/m3u8" metadata:metadata streamDuration:0 customData:nil];

  [_gcChannel loadMedia:mediaInformation autoplay:YES playPosition:startTime];

.htaccess 设置为:

<Files "wp-config.php">
    Order allow,deny
    Deny from all
    Header set Access-Control-Allow-Origin "*"
</Files>

当我从我的 iOS 设备流式传输到 chromeCast 时,我在电视上看到 www.myURL.com/Cast/mpl.html 页面,只有它填写了:

Media Player State: 'underflow true'
Media Host State 'fatal error code = 3'
Media Protocol ' HLS'
.....
License Server URL:
Manifest Credentials: false
Segment Credentials: false
License Credentials: false

我的 mpl.html 来自 https://github.com/googlecast/CastMediaPlayerStreamingDRM然后我从谷歌的网站示例中复制并粘贴:https://google-developers.appspot.com/cast/docs/player?hl=id

<!DOCTYPE html>
<html>
<head>
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
<title>Sample Receiver with Media Player Library for DASH/SS/HLS Streaming with DRMs</title>
<!--
    Cast APIs
-->
<script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/receiver/2.0.0/cast_receiver.js"></script>
<!--
    Cast Media Library
-->
<script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/mediaplayer/0.7.0/media_player.js"></script>
<script type="text/javascript" src="mpl.js"></script>

<style>
    body {
        overflow:hidden;
    }
    video {
        height:auto;
        width:100%;
        text-align: center;
        border:0px solid silver;
        display: block;
        vertical-align: middle;
        color: #FFFFFF;
        background-color: #000000;
        font-weight: bold;
        font-family: Verdana, Geneva, sans-serif;
        font-size:40px;
        float:left;
        z-index: 1;
        position:absolute;
    }
    #messages {
        color: #FFFFFF;
        float: left;
        top:10px;
        left:20px;
        margin-left: 5px;
        margin-top:  5px;
        z-index:2;
        position:absolute;
        font-weight: bold;
        font-size: 90%;
        width:95%;
        background-color: rgba(0,0,0,0.5);
        opacity:0.6;
    }

    #messages span {
        font-weight: normal;
    }
</style>
</head>
<body>
<div id="messages">
  <div style="font-size:140%; font-weight:bold; margin-left:0px;" id="title">Sample Receiver with Media Player Library for DASH/SS/HLS Streaming with DRMs</div>
  <div>App State: <span id="applicationState">-</span></div>
  <div>Sender Count: <span id="senderCount">0</span></div>
  <div>Media Element State: <span  id="mediaElementState">-</span></div>
  <div>Volume State: <span  id="volumeMessage">Starting volume, unchanged at 0.5</span></div>
  <hr>
  <div>Cast Receiver Manager Message: <span  id="castReceiverManagerMessage">-</span></div>
  <hr>
  <div>Media Manager Message: <span  id="mediaManagerMessage">-</span></div>
  <hr>
  <div>Message Bus Message: <span  id="messageBusMessage">-</span></div>
  <hr>
  <div style="font-size:110%;font-weight:bold;">Media Player Library: Player - Host - Protocol</div>
  <div>Media Player State: <span id="mediaPlayerState">-</span></div>
  <div>Media Host State: <span id="mediaHostState">-</span></div>
  <div>Media Protocol: <span id="mediaProtocol">-</span></div>
  <div>Stream Count: <span id="streamCount"></span></div>
  <div>Video Stream Index: <span id="videoStreamIndex"></span></div>
  <div>Video Codecs: <span id="streamVideoCodecs"></span></div>
  <div>Video Bitrates: <span id="streamVideoBitrates"></span></div>
  <div>Video Bitrates Index: <span id="videoQualityIndex"></span></div>
  <div>Video Quality Bandwidth: <span id="streamVideoQuality"></span></div>
  <div>Audio Stream Index: <span id="audioStreamIndex"></span></div>
  <div>Audio Codecs: <span id="streamAudioCodecs"></span></div>
  <div>Audio Bitrates: <span id="streamAudioBitrates"></span></div>
  <div>Audio Bitrates Index: <span id="audioQualityIndex"></span></div>
  <div>Audio Quality Bandwidth: <span id="streamAudioQuality"></span></div>
  <div>Captions: <span id="captions"></span></div>
  <div>License Server URL: <span id="licenseUrl"></span></div>
  <div>Manifest Credentials: <span id="manifestCredentials">false</span></div>
  <div>Segment Credentials: <span id="segmentCredentials">false</span></div>
  <div>License Credentials: <span id="licenseCredentials">false</span></div>
</div>
<video id="vid" style="height:95%; width:100%;"></video>


<script type="text/javascript">
window.onload = function() 
{
if (window.location.href.indexOf('Debug=true') != -1) 
{
  cast.receiver.logger.setLevelValue(cast.receiver.LoggerLevel.DEBUG);
  cast.player.api.setLoggerLevel(cast.player.api.LoggerLevel.DEBUG);
}

var mediaElement = document.getElementById('vid');


window.mediaManager = new cast.receiver.MediaManager(mediaElement);

window.defaultOnLoad = mediaManager.onLoad;
mediaManager.onLoad = function (event) 
{
  if (window.player !== null) 
  {
    player.unload();    // Must unload before starting again.
    window.player = null;
  }

if (event.data['media'] && event.data['media']['contentId']) 
{
  console.log('Starting media application');
  var url = event.data['media']['contentId'];

  window.host = new cast.player.api.Host(
    {'mediaElement':mediaElement, 'url':url});
  var ext = url.substring(url.lastIndexOf('.'), url.length);
  var initStart = event.data['media']['currentTime'] || 0;
  var autoplay = event.data['autoplay'] || true;
  var protocol = null;
  mediaElement.autoplay = autoplay;  // Make sure autoplay get's set
  if (url.lastIndexOf('.m3u8') >= 0) 
  {
    // HTTP Live Streaming
    protocol = cast.player.api.CreateHlsStreamingProtocol(host);
  } else if (url.lastIndexOf('.mpd') >= 0) 
  {
    // MPEG-DASH
    protocol = cast.player.api.CreateDashStreamingProtocol(host);
  } else if (url.indexOf('.ism/') >= 0) {
// Smooth Streaming
    protocol = cast.player.api.CreateSmoothStreamingProtocol(host);
  }

  host.onError = function(errorCode) {
    console.log("Fatal Error - "+errorCode);
    if (window.player) {
      window.player.unload();
      window.player = null;
    }
  };
  host.updateSegmentRequestInfo = function(requestInfo) 
  {
    requestInfo.withCredentials = true;
  };
  console.log("we have protocol "+ext);
  if (protocol !== null) 
  {
    console.log("Starting Media Player Library");
    window.player = new cast.player.api.Player(host);
    window.player.load(protocol, initStart);
  }
  else 
  {
    window.defaultOnLoad(event);    // do the default process
  }
}
}
window.player = null;
console.log('Application is ready, starting system');
window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
castReceiverManager.start();
};
</script>

</body>
</html>

最佳答案

streamType 设置为 GCKMediaStreamTypeNone 并将 contentType 设置为 "video/m3u" 对我来说使用符合 HLS 的 AVC/AAC 流默认接收者:

GCKMediaInformation *mediaInformation =
      [[GCKMediaInformation alloc] initWithContentID:
              @"https://example.com/path/to/playlist.m3u8"
                                          streamType:GCKMediaStreamTypeNone
                                         contentType:@"video/m3u"
                                            metadata:metadata
                                      streamDuration:0
                                          customData:nil];

关于ios - Google ChromeCast 从 iOS 播放 m3u8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24431940/

相关文章:

chromecast - 让 Chrome-Cast 应用程序保持事件状态并显示在通知栏中

android - Chromecast RemoteMediaClient 有时不适用于某些操作,例如 "play"和 "pause"

ios - ios-TableView内的动画扩展TableView(在第一行上点击)

ios - Objective-C - 如何遵守多种协议(protocol)?

Android OpenGL 视频捕获

video - 如何判断视频文件是否损坏? FFmpeg?

video - Flutter - video_player 全屏

ios - Chromecast 在不重新启动流的情况下更新流的元数据

ios - 如何从代码中分别为每个 View Controller 阻止横向位置?

ios - 使用零对象为PFRelation创建PFQuery