探索 Vine API





5.00/5 (5投票s)
如何通过 API 将视频上传到 Vine
背景
我将这篇文章命名为“探索 Vine API”,也可以命名为“玩转 Vine API”,因为 Vine 并没有提供官方 API,所以我写了一个简单的教程,通过一个示例来展示如何使用 API 将视频上传到这个平台。
什么是 Vine?
Vine 是一个短视频分享网站。它允许用户分享时长不超过 6 秒的视频。它适用于 Android、iOS 和 Windows Phone。它的网站展示了各种各样的短视频。用户可以使用 Google 或 Facebook 帐户注册。
关于 Vine API 的信息
Vine 是 Twitter 的产品。他们没有像 Twitter 那样提供任何公共 API。因此,一些人对该应用程序进行了逆向工程,并找到了 API 接口。非官方 API 包含许多接口,但在这里我们将了解如何将视频分享到 Vine。
Vine 应用程序不允许从存储位置选择视频。用户必须从应用程序内的相机录制视频,尽管它提供了定格动画录制。该应用程序以 MP4 格式录制视频,分辨率为 480x480。让我们逐个了解 API。
探索 API
在实现代码示例以展示如何上传带有类别和标题的视频时,我使用了这两个链接作为参考。这两个都是关于非官方 Vine API 的文档/GitHub 项目:VineAPI 和 Vine.app API 参考。
登录 Vine
众所周知,Vine 提供了社交网络登录功能。因此,API 将这些社交凭据作为用户名和密码。要登录 Vine 并获取会话 ID,您必须使用 POST 方法将用户名和密码作为多部分表单数据请求发送。以下是端点、代码和响应格式。
POST
https://api.vineapp.com/users/authenticate
发布数据
username=xxx@example.com
password=xxx
/// <summary>
/// Logs in to Vine and returns session ID.
/// </summary>
public static async Task<string> VineLoginAsync(string Username, string Password)
{
try
{
string _VineSessionId = string.Empty;
var multiPartData = new HttpMultipartFormDataContent();
multiPartData.Add(new HttpStringContent(Username), "username");
multiPartData.Add(new HttpStringContent(Password), "password");
HttpClient httpClient = new HttpClient();
var HttpReq = await httpClient.PostAsync
(new Uri("https://api.vineapp.com/users/authenticate"), multiPartData);
if (HttpReq.IsSuccessStatusCode)
{
var JsonResponse = await HttpReq.Content.ReadAsStringAsync();
var obj = JsonObject.Parse(JsonResponse);
_VineSessionId = obj.GetNamedObject("data").GetNamedString("key");
ApplicationData.Current.LocalSettings.Values["VINE_SESSION_ID_KEY"] =
_VineSessionId;
}
return _VineSessionId;
}
catch (Exception ex)
{
}
}
获取频道
频道是一种在上传视频时使用的类别。通过设置频道 ID,可以将视频放到指定的频道中。要获取频道名称及其相应的 ID,您需要向以下给定的端点发送一个 GET 请求。这是一个无参数的服务调用。以下是代码和 JSON 输出格式。
GET
https://api.vineapp.com/channels/featured
/// <summary>
/// Returns Vine channel name with its ID.
/// </summary>
public static async Task<List<KeyValuePair<string, string>>> GetChannelsAsync()
{
try
{
var HttpReq = await httpClient.GetAsync(new Uri
("https://api.vineapp.com/channels/featured"));
if (HttpReq.IsSuccessStatusCode)
{
var ResponseStr = await HttpReq.Content.ReadAsStringAsync();
var JsonObj = JsonObject.Parse(ResponseStr);
var array = JsonObj["data"].GetObject()["records"].GetArray();
var ChannelDictionary = new List<KeyValuePair<string, string>>();
foreach (var item in array)
{
ChannelDictionary.Add(new KeyValuePair<string, string>
(item.GetObject()["channelId"].GetNumber().ToFloatingPointString(),
item.GetObject()["channel"].GetString()));
}
return ChannelDictionary;
}
}
catch (Exception ex)
{
}
}
在这里,您必须使用一个扩展方法将大整数转换为string
。如果您只使用ToString()
方法,它将以科学计数法的形式返回数字。例如,如果频道 ID 是1070175184667013120
,那么如果您使用ToString()
,您将得到“1.07017518466701E+18
”。因此,您应该使用ToFloatingPointString()
扩展方法,如下所示。
private static readonly Regex rxScientific = new Regex(@"^(?<sign>-?)(?<head>\d+)
(\.(?<tail>\d*?)0*)?E(?<exponent>[+\-]\d+)$",
RegexOptions.IgnoreCase|RegexOptions.ExplicitCapture|RegexOptions.CultureInvariant);
public static string ToFloatingPointString(this double value)
{
return ToFloatingPointString(value, NumberFormatInfo.CurrentInfo);
}
public static string ToFloatingPointString(double value, NumberFormatInfo formatInfo)
{
string result = value.ToString("r", NumberFormatInfo.InvariantInfo);
Match match = rxScientific.Match(result);
if (match.Success)
{
Debug.WriteLine("Found scientific format: {0} => [{1}] [{2}] [{3}] [{4}]",
result, match.Groups["sign"], match.Groups["head"],
match.Groups["tail"], match.Groups["exponent"]);
int exponent = int.Parse(match.Groups["exponent"].Value,
NumberStyles.Integer, NumberFormatInfo.InvariantInfo);
StringBuilder builder = new StringBuilder(result.Length + Math.Abs(exponent));
builder.Append(match.Groups["sign"].Value);
if (exponent >= 0)
{
builder.Append(match.Groups["head"].Value);
string tail = match.Groups["tail"].Value;
if (exponent < tail.Length)
{
builder.Append(tail, 0, exponent);
builder.Append(formatInfo.NumberDecimalSeparator);
builder.Append(tail, exponent, tail.Length-exponent);
}
else
{
builder.Append(tail);
builder.Append('0', exponent-tail.Length);
}
}
else
{
builder.Append('0');
builder.Append(formatInfo.NumberDecimalSeparator);
builder.Append('0', (-exponent)-1);
builder.Append(match.Groups["head"].Value);
builder.Append(match.Groups["tail"].Value);
}
result = builder.ToString();
}
return result;
}
上传视频
如您所知,Vine 仅允许分辨率为 480x480 且时长不超过 6 秒的视频。因此,首先,您必须根据此类规范修改视频(如果它不符合)。上传过程分三个服务调用进行。
首先,您必须上传视频。您必须发送PUT
请求。请求的标头将具有 Vine 会话 ID。请求的内容将是二进制格式的视频。请求的内容类型将是 video/mp4。具有“X-Upload-Key
”键的PUT
请求的响应标头将具有已上传视频的 URL,您需要提取该 URL,因为在第三步中我们需要该 URL。以下是端点、JSON 响应和代码。
PUT
https://media.vineapp.com/upload/videos/1.3.1.mp4.
/// <summary>
/// Uploads video to Vine and returns Vine URL for video.
/// </summary>
public static async Task<string> UploadVineVideoAsync(StorageFile Video, string VineSessionId)
{
try
{
string _VideoUrl = string.Empty;
var binaryContent = new HttpBufferContent(await FileIO.ReadBufferAsync(Video));
binaryContent.Headers.Add("Content-Type", "video/mp4");
var request = new HttpRequestMessage
(HttpMethod.Put, new Uri("https://media.vineapp.com/upload/videos/1.3.1.mp4"));
request.Headers.Add("vine-session-id", VineSessionId);
request.Content = binaryContent;
var HttpReq = await httpClient.SendRequestAsync(request);
if (HttpReq.IsSuccessStatusCode)
{
var ResonseHeader = HttpReq.Headers;
ResonseHeader.TryGetValue("X-Upload-Key", out _VideoUrl);
}
return _VideoUrl;
}
catch (Exception ex)
{
return string.Empty;
}
}
我们的第二步是上传视频的缩略图。缩略图也应为 480x480 分辨率。它的内容类型应为 image/jpeg。服务调用模式与上传视频相同。您必须通过设置其标头(带有 Vine 会话 ID)来发送PUT
请求,并且其内容将具有二进制格式的图像。成功的服务调用将在响应标头中返回缩略图 URL,键为“X-Upload-Key
”。提取它,将在第三步中使用。
PUT
https://media.vineapp.com/upload/thumbs/1.3.1.mp4.jpg.
/// <summary>
/// Uploads video thumbnail image to Vine and returns Vine URL for thumbnail image.
/// </summary>
public static async Task<string> UploadVineThumbAsync(StorageFile Video, string VineSessionId)
{
try
{
var VideoThumb = await Video.GetThumbnailAsync
(Windows.Storage.FileProperties.ThumbnailMode.SingleItem);
Byte[] VideoThumbBytes = new Byte[VideoThumb.Size];
var VideoThumbBuffer = VideoThumbBytes.AsBuffer();
string _ThumbUrl = string.Empty;
var binaryContent = new HttpBufferContent(VideoThumbBuffer);
binaryContent.Headers.Add("Content-Type", "image/jpeg");
var request = new HttpRequestMessage(HttpMethod.Put,
new Uri("https://media.vineapp.com/upload/thumbs/1.3.1.mp4.jpg"));
request.Headers.Add("vine-session-id", VineSessionId);
request.Content = binaryContent;
var HttpReq = await httpClient.SendRequestAsync(request);
if (HttpReq.IsSuccessStatusCode)
{
var ResonseHeader = HttpReq.Headers;
ResonseHeader.TryGetValue("X-Upload-Key", out _ThumbUrl);
var ResonseStr = await HttpReq.Content.ReadAsStringAsync();
}
return _ThumbUrl;
}
catch (Exception ex)
{
return string.Empty;
}
}
现在,最后一个服务调用是一个POST
服务调用,它将参数作为视频 URL、缩略图 URL、频道 ID、Vine 描述和实体。POST
请求标头将具有 Vine 会话密钥。以下是代码和端点。请注意,“实体”参数的目的尚未被发现,因此空字符串将适用于它,因为它是一个强制性参数。
/// <summary>
/// Uploads Vine.
/// </summary>
public static async Task PostVineAsync(string VideoUrl, string ThumbUrl,
string ChannelId, string Description, string Entities)
{
try
{
httpClient.DefaultRequestHeaders.Add("vine-session-id", VineSessionId);
var multiPartData = new HttpMultipartFormDataContent();
multiPartData.Add(new HttpStringContent(VideoUrl), "videoUrl");
multiPartData.Add(new HttpStringContent(ThumbUrl), "thumbnailUrl");
multiPartData.Add(new HttpStringContent(ChannelId), "channelId");
multiPartData.Add(new HttpStringContent(string.IsNullOrWhiteSpace(Description) ?
"Default Description" : Description), "description");
multiPartData.Add(new HttpStringContent(Entities), "entities");
var HttpReq = await httpClient.PostAsync
(new Uri("https://api.vineapp.com/posts"), multiPartData);
if (HttpReq.IsSuccessStatusCode)
{
var ResonseHeader = HttpReq.Headers;
var ResonseStr = await HttpReq.Content.ReadAsStringAsync();
await new MessageDialog
("Video uploaded successfully on Vine", "App name").ShowAsync();
}
}
catch (Exception ex)
{
}
}
参考文献
正如我之前所说,在撰写文章和实现代码示例时,我使用了这两个链接作为参考
历史
- 2015 年 4 月 6 日:初始版本