1

我正在尝试使用 .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--

我见过的谷歌最好的信息是使用以下方法进行插入:

/// <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。

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

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

有没有人能够让流视频通过 .NET 工作(使用 Mirror 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

提前谢谢大家!

4

3 回答 3

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();
                }
于 2013-10-08T06:04:42.983 回答
1

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

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

Glass 实际上支持从时间线直接进行渐进式下载和 hls 流式传输。您需要创建一个带有缩略图参考的标准图像卡,然后将 PLAY_VIDEO 菜单项添加到您的菜单项列表中。我已经有一段时间没有进行任何 .net 编程了,但我猜这应该可以工作。

new MenuItem() {Action = "PLAY_VIDEO", Payload = mediaLink}
于 2013-10-12T10:10:12.653 回答
0

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

您提到的视频 URL 与我可以使用 Curl 开始工作的视频 URL 相同,如本答案中所述:

更新 XE6 后使用 video/vnd.google-glass.stream-url 附加视频

(找我的答案,不是选的那个)

这意味着您的请求中有问题,响应是什么?这是我发送工作请求时的示例响应:

    {
 "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 不是很好,所以您可能需要修改它):

<?php

$file = 'out.txt';

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

file_put_contents($file, $current);

?>

我认为您应该专注于您发布的代码的第二部分,它看起来非常接近我的工作,只需打印出其中一些项目,与我的示例相比应该很清楚出了什么问题。

于 2013-07-13T05:18:07.843 回答