【问题标题】:C#: Upload Photo To Twitter From UnityC#:从 Unity 将照片上传到 Twitter
【发布时间】:2015-05-15 10:51:03
【问题描述】:

目前我正在与团结合作。在这个项目中,我需要在 Twitter 上发布一些带有图像的状态。但是,我在将图片上传到 Twitter 时遇到了问题。

这是我用来上传图片的代码:

private const string UploadMediaURL = "https://upload.twitter.com/1.1/media/upload.json";
    public static IEnumerator UploadMedia(string consumerKey, string consumerSecret, string filePath, AccessTokenResponse response){
                Dictionary<string, string> mediaParameters = new Dictionary<string, string>();
                mediaParameters.Add("media", System.Convert.ToBase64String(File.ReadAllBytes(filePath)));

                // Add data to the form to post.
                WWWForm mediaForm = new WWWForm();
                mediaForm.AddField("media", System.Convert.ToBase64String(File.ReadAllBytes(filePath)));

                print (System.Convert.ToBase64String (File.ReadAllBytes (filePath)));

                // HTTP header
                var mediaHeaders = new Hashtable();
                mediaHeaders["Authorization"] = GetHeaderWithAccessToken("POST", UploadMediaURL, consumerKey, consumerSecret, response, mediaParameters);

                WWW mw = new WWW(UploadMediaURL, mediaForm.data, mediaHeaders);
                yield return mw;

                if (!string.IsNullOrEmpty (mw.error)) {
                    Debug.Log(string.Format("PostTweet - failed. {0}"));
                } else {
                    SetMediaWeb(mw);
                }
            }

当我调用上述方法时,出现以下错误:

UriFormatException:Uri 超过了最大 {0} 个字符。 System.Uri.EscapeDataString(System.String stringToEscape)

仅供参考,图片不大,只有23 kb,图片类型为png。

我的代码有什么问题。感谢您的帮助。

【问题讨论】:

  • 异常是否来自对 new WWW(...) 的调用?什么是堆栈跟踪?

标签: c# twitter unity3d upload media


【解决方案1】:

我也有同样的问题。我通过减小我试图发布的图像的大小来解决它。我不确定限制是多少,但我发现 256*256 jpg 工作正常。

我还注意到您的代码与我的有点不同。这是我的代码

Dictionary<string, string> parameters = new Dictionary<string, string>();
string encoded64ImageData = ImageToBase64( imageData );
parameters.Add("media_data", encoded64ImageData );

// Add data to the form to post.
WWWForm form = new WWWForm();
form.AddField( "media_data", encoded64ImageData );

// HTTP header
Dictionary<string, string> headers = new Dictionary<string, string>();
string url = UploadMediaURL;
string auth = GetHeaderWithAccessToken("POST", url, consumerKey, consumerSecret, accessToken, parameters);
headers.Add( "Authorization", auth );
headers.Add( "Content-Transfer-Encoding", "base64" );

WWW web = new WWW(url, form.data, headers);
yield return web;

Twitter 文档说您在提交 64 位编码媒体时需要使用 media_data。 media/upload

我还读到您需要在提交 64 位数据表单时定义“Content-Transfer-Encoding=base64”...这可能是必要的,也可能不是,我没有尝试过。

【讨论】:

    【解决方案2】:

    我没有足够的代表发表评论,但安东尼的代码有助于推动事情的发展。

    问题是库使用的 Uri.EscapeDataString 方法有字符限制,因此如果您的文件很大(因此是长的 base-64 字符串),该方法将无法添加正确的签名/timestamp 的东西,因此在尝试上传媒体时会导致 401。

    因此,一个简单的解决方法是将 base64 字符串拆分为更小的块,转义这些块,然后将它们拼凑在一起以进行最终的 POST。 下面的代码实际上取自另一个关于 Uri.EscapeDataString 的 SO 问题。 只需在构建表单对象时调用此方法而不是 Uri.EscapeDataString 就可以了。

    private static string EscapeString(string originalString)
        {
            int limit = 2000;
    
            StringBuilder sb = new StringBuilder();
            int loops = originalString.Length / limit;
    
            for (int i = 0; i <= loops; i++)
            {
                if (i < loops)
                {
                    sb.Append(Uri.EscapeDataString(originalString.Substring(limit * i, limit)));
                }
                else
                {
                    sb.Append(Uri.EscapeDataString(originalString.Substring(limit * i)));
                }
            }
            return sb.ToString();
        }
    

    我一直在我的最新游戏中使用它,它允许玩家轻松上传动画 GIF,并且尚未发现任何问题,我们的最大文件大小约为 2mb 并且运行良好。

    祝你好运!

    【讨论】:

    • 正确 - 这不再给出 URI 问题,但实际上并没有上传图像!除了安东尼的建议之外,您是否进行了任何更改?
    【解决方案3】:

    您应该只在 WWWForm 对象中添加媒体参数。根据documentation,上传媒体时:

    OAuth 的处理方式略有不同。在计算 OAuth 签名基字符串或签名时,不使用 POST 或查询字符串参数。仅使用 oauth_* 参数。

    在参数字典中添加媒体在创建签名期间生成错误(由GetHeaderWithAccessToken制作)。

    【讨论】:

    • 嗨克劳迪奥!您是如何通过 POST 上传图片的?提前谢谢!
    【解决方案4】:

    这是我正在使用的代码,其中包括带有状态的帖子。我正在使用 Lets Tweet 的代码:https://www.assetstore.unity3d.com/en/#!/content/536 感谢之前发布的所有帮助图片上传部分正常工作的人。通过 Patrick 的更改,这应该可以让您上传和发布最大为 5MB 的任何图像或媒体文件。

        Dictionary<string, string> mediaParameters = new Dictionary<string, string> ();
                string mediaString = System.Convert.ToBase64String (File.ReadAllBytes (filePath));
                mediaParameters.Add ("media_data", mediaString);
                mediaParameters.Add ("status", text);
    
                // Add data to the form to post.
                WWWForm mediaForm = new WWWForm ();
                mediaForm.AddField ("media_data", mediaString);
                mediaForm.AddField ("status", text);
    
    //          Debug.Log (System.Convert.ToBase64String (File.ReadAllBytes (filePath)));
    
                // HTTP header
                Dictionary<string, string> mediaHeaders = new Dictionary<string, string> ();
                string url = UploadMediaURL;
                string auth = GetHeaderWithAccessToken ("POST", UploadMediaURL, consumerKey, consumerSecret, response, mediaParameters);
                mediaHeaders.Add ("Authorization", auth);
                mediaHeaders.Add ("Content-Transfer-Encoding", "base64");
    
                WWW mw = new WWW (UploadMediaURL, mediaForm.data, mediaHeaders);
                yield return mw;
    
                string mID = Regex.Match(mw.text, @"(\Dmedia_id\D\W)(\d*)").Groups[2].Value;
    
                Debug.Log ("response from media request : " + mw.text);
    
                Debug.Log ("mID = " + mID);
    
                if (!string.IsNullOrEmpty (mw.error)) {
                    Debug.Log (string.Format ("PostTweet - failed. {0}\n{1}", mw.error, mw.text));
                    callback (false);
                } else {
                    string error = Regex.Match (mw.text, @"<error>([^&]+)</error>").Groups [1].Value;
    
                    if (!string.IsNullOrEmpty (error)) {
                        Debug.Log (string.Format ("PostTweet - failed. {0}", error));
                        callback (false);
                    } else {
                        callback (true);
                    }
                }
    
                Dictionary<string, string> parameters = new Dictionary<string, string>();
                parameters.Add("status", text);
                parameters.Add ("media_ids", mID);
    
                // Add data to the form to post.
                WWWForm form = new WWWForm();
                form.AddField("status", text);
                form.AddField ("media_ids", mID);
    
                // HTTP header
                var headers = new Dictionary<string, string>();
                headers["Authorization"] = GetHeaderWithAccessToken("POST", PostTweetURL, consumerKey, consumerSecret, response, parameters);
    
                WWW web = new WWW(PostTweetURL, form.data, headers);
                yield return web;
    
                if (!string.IsNullOrEmpty(web.error))
                {
                    Debug.Log(string.Format("PostTweet - failed. {0}\n{1}", web.error, web.text));
                    callback(false);
                }
                else
                {
                    string error = Regex.Match(web.text, @"<error>([^&]+)</error>").Groups[1].Value;
    
                    if (!string.IsNullOrEmpty(error))
                    {
                        Debug.Log(string.Format("PostTweet - failed. {0}", error));
                        callback(false);
                    }
                    else
                    {
                        callback(true);
                    }
                }
    

    【讨论】:

      猜你喜欢
      • 2015-09-30
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多