通过.NET Mirror API附加视频流

时间:2013-07-12 18:01:45

标签: google-mirror-api google-glass

我正在尝试使用.NET Mirror API附加视频流,但我遇到了一些麻烦。

我似乎无法找到支持此处引用格式的方法:

POST /upload/mirror/v1/timeline HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Content-Type: multipart/related; boundary="mymultipartboundary"
Content-Length: {length}

--mymultipartboundary
Content-Type: application/json; charset=UTF-8

{ "text": "Skateboarding kittens" }
--mymultipartboundary
Content-Type: video/vnd.google-glass.stream-url

http://example.com/path/to/kittens.mp4
--mymultipartboundary--

我见过Google的最佳信息是使用以下方法进行插入:

/// <summary>
/// Insert a new timeline item in the user's glass with an optional
/// notification and attachment.
/// </summary>
/// <param name='service'>Authorized Mirror service.</param>
/// <param name='text'>Timeline Item's text.</param>
/// <param name='contentType'>
/// Optional attachment's content type (supported content types are
/// "image/*", "video/*" and "audio/*").
/// </param>
/// <param name='attachment'>Optional attachment stream</param>
/// <param name='notificationLevel'>
/// Optional notification level, supported values are null and
/// "AUDIO_ONLY".
/// </param>
/// <returns>
/// Inserted timeline item on success, null otherwise.
/// </returns>
public static TimelineItem InsertTimelineItem(MirrorService service,
    String text, String contentType, Stream attachment,
    String notificationLevel) {

  TimelineItem timelineItem = new TimelineItem();
  timelineItem.Text = text;
  if (!String.IsNullOrEmpty(notificationLevel)) {
    timelineItem.Notification = new NotificationConfig() {
      Level = notificationLevel
    };
  }
  try {
    if (!String.IsNullOrEmpty(contentType) && attachment != null) {
      // Insert both metadata and media.
      TimelineResource.InsertMediaUpload request = service.Timeline.Insert(
          timelineItem, attachment, contentType);
      request.Upload();
      return request.ResponseBody;
    } else {
      // Insert metadata only.
      return service.Timeline.Insert(timelineItem).Fetch();
    }
  } catch (Exception e) {
    Console.WriteLine("An error occurred: " + e.Message);
    return null;
  }
}

但是,此代码将内容“附加”为一个流(这对于上传图像非常有用,我已经测试并且有效)。但是,流媒体视频只需要视频的网址。

我尝试将URL的字符串表示形式作为流发送,但结果只是一个无限加载的视频。

我已经成功地通过使用我的身份验证令牌和上面的POST请求发出cURL请求来播放视频,所以我知道视频本身不是问题。

有没有人能够通过.NET获得流媒体视频(使用镜像API或某种自定义WebRequest?)我尝试过自己创建WebRequest,但是我得到的是400一个回应。

供参考,我试过的其他代码:

var request = WebRequest.CreateHttp(baseAddress + method);
request.Method = "POST";
request.Headers.Add("Authorization", string.Format("Bearer {0}", auth));

string itemJson = JsonConvert.SerializeObject(item.Item, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });

 string contentFormat = "--MyBound\nContent-Type: application/json; charset=UTF-8\n\n{0}\n--MyBound\nContent-Type: video/vnd.google-glass.stream-url\n\n{1}\n--MyBound--";
 string content = string.Format(contentFormat, new[] { itemJson, item.VideoUrl });
 request.ContentLength = content.Length;
 request.ContentType = "multipart/related; boundary=\"MyBound\"";
 var rs = request.GetRequestStream();
 using (var sw = new StreamWriter(rs))
 {
     sw.Write(content);
 }

 var response = request.GetResponse();

其中item是我编写的一个类,其中包含VideoUrl作为字符串,以及Item(来自Mirror API的TimelineItem),以及我正在使用的视频Url:

http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8

先谢谢大家!

3 个答案:

答案 0 :(得分:1)

我已成功使用以下代码。

 String mediaLink = "url_to_your_video.mp4";
        String message = "you_message";

MirrorService Service = new MirrorService(new BaseClientService.Initializer()
                                                          {
                                                              Authenticator = Utils.GetAuthenticatorFromState(state)
                                                          });

            TimelineItem timelineItem = new TimelineItem();

            timelineItem.Creator = new Contact()
            {
                Id = Config.CREATOR_ID,
                DisplayName = Config.DISPLAY_NAME,
            };


            timelineItem.Notification = new NotificationConfig() { Level = "DEFAULT" };
            timelineItem.MenuItems = new List<MenuItem>()
                                         {
                                             new MenuItem() {Action = "NAVIGATE"},
                                             new MenuItem() {Action = "DELETE"},
                                             new MenuItem() {Action = "SHARE"},
                                         };


            if (!String.IsNullOrEmpty(mediaLink))
                {
                Stream stream = null;
                if (mediaLink.StartsWith("/"))
                    {
                    stream = new StreamReader(Server.MapPath(mediaLink)).BaseStream;
                    }
                else
                    {
                    HttpWebRequest request = WebRequest.Create(mediaLink) as HttpWebRequest;
                    HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                    byte[] b = null;
                    using (Stream streamFromWeb = response.GetResponseStream())
                    using (MemoryStream ms = new MemoryStream())
                        {
                        int count = 0;
                        do
                            {
                            byte[] buf = new byte[1024];
                            count = streamFromWeb.Read(buf, 0, 1024);
                            ms.Write(buf, 0, count);
                            } while (streamFromWeb.CanRead && count > 0);
                        b = ms.ToArray();
                        stream = new MemoryStream(b);
                        }
                    }


                Service.Timeline.Insert(timelineItem, stream, "video/mp4").Upload();
                }
            else
                {
                Service.Timeline.Insert(timelineItem).Fetch();
                }

答案 1 :(得分:1)

Sanath的代码适用于小文件,但你真的不想做任何大到Glass的二进制上传。

Glass网站上的文档有点误导,他们详细介绍了如何进行多部分上传,但随后告诉您他们并不是一个好主意并简要提及您应该如何做。

Glass实际上支持渐进式下载和直接从时间线流式传输。您将要创建带有缩略图引用的标准图像卡,然后将PLAY_VIDEO菜单项添加到菜单项列表中已经有一段时间了,因为我已经完成了任何.net编程,但我和#39;我猜这应该有用。

new MenuItem() {Action = "PLAY_VIDEO", Payload = mediaLink}

答案 2 :(得分:0)

无限负载可能意味着视频格式不正确或不再提供服务。我认为这不是这种情况。

您提到的视频网址与我使用Curl工作的视频网址相同,如本答案所示:

Attaching video with video/vnd.google-glass.stream-url after Update XE6

(寻找我的答案,这不是选定的答案)

这意味着您的请求中存在错误,响应是什么?以下是发送工作请求时的示例响应:

    {
 "kind": "mirror#timelineItem",
 "id": "44359ebc-ff49-4d48-a609-2f6ab1354ae3",
 "selfLink": "https://www.googleapis.com/mirror/v1/timeline/44359ebc-ff49-4d48-a
609-2f6ab1354ae3",
 "created": "2013-07-13T05:05:30.004Z",
 "updated": "2013-07-13T05:05:30.004Z",
 "etag": "\"ZECOuWdXUAqVdpmYErDm2-91GmY/h_jXHSw50TrLSr94HZGFIGAlPxs\"",
 "text": "Sweetie",
 "attachments": [
  {
   "id": "bs:9088a6e2-b8ad-4e1d-a544-5d7e858e5e3f",
   "contentType": "video/vnd.google-glass.stream-url",
   "contentUrl": "https://www.googleapis.com/mirror/v1/timeline/44359ebc-ff49-4d
48-a609-2f6ab1354ae3/attachments/bs:9088a6e2-b8ad-4e1d-a544-5d7e858e5e3f?alt=med
ia"
  }
 ]
}

我刚刚做了这件事,确实在Glass上看到了哔哔声 - bop视频。

因此,检查响应,并查看是否可以打印出请求,我的看起来像这样:

--mymultipartboundary
Content-Type: application/json; charset=UTF-8

{ "text": "Sweetie" }
--mymultipartboundary
Content-Type: video/vnd.google-glass.stream-url

http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8
--mymultipartboundary--

查看请求的一种方法是使用像Charles,Fiddler或Wireshark这样的嗅探器,如果这不起作用,请将您的请求指向这样的php文件,然后查看out.txt(注意我的php isn'太棒了所以你可能需要修改它):

<?php

$file = 'out.txt';

$current .= print_r($_GET, true);
$current .= print_r($_POST,true);
$current .= print_r(getallheaders(),true);

file_put_contents($file, $current);

?>

我认为您应该专注于您发布的第二部分代码,它看起来非常接近我的工作,只打印出一些这些项目,并且应该通过与我的示例进行比较来明确哪些是错误的。