I am trying to upload a video to Facebook from an air for android app. the as3 facebook api has the following method for uploading videos
facebookMobile.uploadVideo(method:String, callback:Function = null, params:* = null)
params:* (default = null) — An object containing the title, description, fileName (including extension), and video (FileReference or ByteArray)
i am recording the video using cameraUi and am getting back the location of the file. according to the api i need to pass in this file using either fileReferance or a byteArray as i already have the location of the file i don't want any sort of browse functionality. I am having trouble creating the byteArray (never used it before). i am getting a 353 error from facebook: you must select a video file.
Bellow is my attempt at creating the bytearray
public function UICompleteHandler(event:MediaEvent):void
{
trace("Welcome back from the camera");
var media:MediaPromise = event.data;
trace("file info "+media.file.url + " - " + media.relativePath + " - " + media.mediaType);
filePath = media.file.url;
trace("Object encoding is: " + inBytes.objectEncoding + "\n\n" + "order file: \n\n");
readFileIntoByteArray(filePath, inBytes);
trace("length 1: "+inBytes.length);
trace("position 1: "+inBytes.position);
inBytes.position = 0; // reset position to beginning
//inBytes.uncompress(CompressionAlgorithm.DEFLATE);
//trace("position 2: "+inBytes.position);
//inBytes.position = 0; //reset position to beginning
trace (inBytes);
}
private function readFileIntoByteArray(fileName:String, data:ByteArray):void
{
var inFile:File = new File(fileName);
trace ("file to byte array "+ inFile.url);
trace ("file name var : "+fileName);
inStream.open(inFile , FileMode.READ);
inStream.readBytes(data);
inStream.close();
}
and video upload code:
public function handleUpload(ev:TouchEvent)
{
trace ("posting to facebook - FileName: "+ accessCamera.fileName + " - FilePath: " + accessCamera.filePath);
var params:Object ={
title:'test upload on FB api',
description:'test upload on FB api',
fileName: accessCamera.fileName,
video: accessCamera.inBytes
}
//trace ("params.video = "+params.video);
FacebookMobile.uploadVideo('me/videos', onComplete, params);
}
private function onComplete( result:Object, fail:Object ):void {
trace("facebook post onComplete called" );
if (result)
{
//result.id is id of post that was just posted
trace ("great");
}
else if (fail)
{
trace("post Failed");
trace('code: '+fail.error.code);
trace('message: '+fail.error.message);
trace('type: '+fail.error.type);
}
}
No need to convert it to a ByteArray. File is an AIR-only class meant to allow you to access the file system directly (as you already are doing). As File extends FileReference, you can simply pass the File object you already have instead.
Related
I am developing an Android app in Unity. I am trying to make UnityWebRequests to work with Vuforia's Web Services API. Currently every method works - GET/PUT/DELETE, but I cannot POST anything, I always get an error:
Error:Generic/unknown HTTP error
Response code:400
Even though according to Vuforia's documentation POST requires the same request body as PUT and I am generating it using the same approach:
public string CreateNewUpdateBody(Text name, Text width, RawImage image, Toggle active_flag, Text application_metadata)
{
dynamic BodyData = new System.Dynamic.ExpandoObject();
if (!string.IsNullOrEmpty(name.text))
{
BodyData.name = name.text; // mandatory for post
}
if (!string.IsNullOrEmpty(width.text))
{
BodyData.width = float.Parse(width.text); // mandatory for post
}
if (image.texture != null)
{
Texture2D texture = (Texture2D)image.texture;
BodyData.image = System.Convert.ToBase64String(ImageConversion.EncodeToJPG(texture)); // mandatory for post
}
if (active_flag.interactable)
{
BodyData.active_flag = active_flag.isOn;
}
if (!string.IsNullOrEmpty(application_metadata.text))
{
BodyData.application_metadata = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(application_metadata.text));
}
string json = JsonConvert.SerializeObject(BodyData);
Debug.Log("Body data: " + json);
return json;
}
Then I send the web request like this:
private IEnumerator PostTarget(MonoBehaviour mono, string postBody)
{
var request = UnityWebRequest.Post(url + "/targets", postBody);
SetHeaders(request); // Must be done after setting the body
Debug.Log("Starting request " + request.method + " " + request.url);
yield return request.SendWebRequest();
while (!request.isDone) yield return null;
if (request.isHttpError || request.isNetworkError)
{
Debug.LogError("Request was not completed");
Debug.LogError("Error:" + request.error + " Response code:" + request.responseCode);
Debug.LogError(request.downloadHandler.text); // result_code is always just "Fail"
mono.StopAllCoroutines();
yield break;
}
else
{
Debug.Log("Request completed successfuly!");
Debug.Log(request.downloadHandler.text);
}
response = JsonUtility.FromJson<ResponsePostNewTarget>(request.downloadHandler.text);
Debug.Log("\nCreated target with id: " + response.target_id);
}
Any thoughts or suggestions? I appreciate the time you take to read this.
If everything works BUT posting data, either 1 vuforia doesn't support it or 2 (most likely) you're missing something.
Try adding this to your request
private UploadHandler GetUploadHandler(string postBody)
{
UploadHandler handler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(postBody));
handler.contentType = "application/json";
return handler;
}
And call it after SetHeaders
request.uploadHandler = GetUploadHandler(postBody);
I'm creating a game for the Facebook Canvas using the official Facebook SDK. Despite using code directly from the Facebook Unity example, I cannot save nor load a score value. I receive no error or message whatsoever - A value of 0 is always returned when I attempt to retrieve the score. Everything else (logging in, posting to the news feed, etc.) is working fine - just not the score management. Also, this occurs both in the Unity editor and on the canvas itself.
I save the player's score like this:
public void SaveScore(int _score)
{
_fbScore = _score;
var _query = new Dictionary<string, string>();
_query["score"] = _fbScore.ToString();
FB.API("/me/scores", Facebook.HttpMethod.POST, delegate(FBResult r) { Util.Log("Result: " + r.Text); }, _query);
//FB.API ("/me/scores", Facebook.HttpMethod.POST, ScoreSaveCallBack, scoreData);
_hiScoreText.text = _fbScore.ToString();
}
I then try to retrieve the score with this method:
public void GetHighScore()
{
if (_fbIsInited)
FB.API ("/app/scores?fields=score,user.limit(20)", Facebook.HttpMethod.GET, GetScoreCallBack);
}
Callback method:
void GetScoreCallBack(FBResult _result)
{
try
{
List<object> _scoresList = Util.DeserializeScores(_result.Text);
foreach(object _score in _scoresList)
{
var _entry = (Dictionary<string,object>) _score;
var _user = (Dictionary<string,object>) _entry["user"];
string _userId = (string)_user["id"];
if (string.Equals(_userId, FB.UserId))
{
_fbScore = GetScoreFromEntry(_entry);
_hiScoreText.text = _fbScore.ToString();
Debug.Log("FB SCORE: + " + _fbScore);
}
}
}
catch (System.Exception _e)
{
Debug.Log(_e.Message);
}
}
As the score returned is always 0, I do not know whether the problem is with the save or load methods.
EDIT:
To make matters worse, out of nowhere, I've started getting these errors when I attempt to post the score:
You are trying to load data from a www stream which had the following error when downloading.
403 Forbidden
UnityEngine.WWW:get_text()
FBResult:get_Text()
FacebookManager:<SaveScore>m__0(FBResult) (at Assets/Scripts/Facebook/FacebookManager.cs:138)
Facebook.<Start>c__Iterator0:MoveNext()
I haven't made any changes to the code, they just started appearing every time!
Shouldn't you pass a numeric app id in this call instead of 'app'?
FB.API ("/123456789/scores?fields=score,user.limit(20)"
You can find your's app code at FacebookDeveloper dashboard, on your app's main panel - it's the 'application identifier'.
Have you also specified this number in unity Facebook|Facebook Settings|App id? That should fix your problems.
On the samsung dforum I found the URL which explains a function startUpload().
but also in forums i found people saying that uploading files by any means is not possible. If so why samsung provide the startUpload() function?
Did anybody tried file upload? please help
Documentation is incorrect. I tested it on UE46ES8000 and successfully uploaded file from USB flash drive connected to TV.
OnComplete callback called instead of OnUploadComplete.
To the end of uploaded data appended string --END_OF_PART--. If you strip it from file, you get your original file.
function OnUploadComplete (msg) {
alert('***OnUploadComplete***' + msg );
}
function OnUploadProgress (msg) {
alert('***OnUploadProgress***' + msg );
}
function fnDnStatus (msg) {
alert('fnCallback' + msg );
var tArrResult = msg.split("?");
for (var i=0; i < tArrResult.length; i++) {
alert("tArrResult[" + i + "] = " + tArrResult[i]);
}
// DownResult: If res=1 success, otherwise ERROR (see end of this file)
}
var DownloadPlugin = document.getElementById("pluginObjectDownload");
DownloadPlugin.OnUploadComplete = OnUploadComplete;
DownloadPlugin.OnUploadProgress = OnUploadProgress;
DownloadPlugin.OnComplete = fnDnStatus;
var sever = '192.168.137.1',
port = 80,
header = 'Header-name: Header value',
body = '[[[FILE_BINARY]]]',
filePath = '$USB_DIR/sda1/textfile.txt',
uploadRatio = '10',
serverType = 1;
DownloadPlugin.StartUpload(sever, port, header, body, filePath, uploadRatio, serverType);
I don't know meaning of header parameter. And I don't know how to specify url other than server root. Data was sent by POST request to http://192.168.137.1:80/.
At server side I saved it with simple script (http://192.168.137.1:80/index.php):
<?php
$t = file_get_contents('php://input');
if(strlen($t) > 1){
echo 'some data arrived';
}
file_put_contents('input.txt', $t);
?>
I just uploaded a video file to my Samsung uhd, through smartthings. Hold-Click on video. Tap share. Send to device. When it's done you will see video just shared in upper right corner. Click on watch video. I'm watching it now but cant figure out where its stored on the tv
I am using Azure Media Services and a Silverlight Player to play the streamed url
I am able to ingest, encode the video file as an asset file but when I go play the streamed url I am facing problem.
I use following code to fetch the url...
context = new CloudMediaContext(_accountName, _accountKey);
IAsset myAsset = GetAsset("UUID:7a32b941-30bd-4c96-bf4e-26df5022eec5");
var theManifest = from f in myAsset.AssetFiles
where f.Name.EndsWith(".ism")
select f;
var manifestFile = theManifest.First();
IAccessPolicy streamingPolicy = _context.AccessPolicies.Create("Streaming policy",
TimeSpan.FromDays(10),
AccessPermissions.Read);
ILocator originLocator = _context.Locators.CreateSasLocator(myAsset, streamingPolicy, DateTime.UtcNow.AddMinutes(-500));
GetAssetSasUrlList(myAsset, originLocator);
string urlForClientStreaming = originLocator.Path + manifestFile.Name + "/manifest";
Console.WriteLine("URL to manifest for client streaming: ");
Console.WriteLine(urlForClientStreaming);
this url comes like --
https://mediasvc06w4dq5k8vd08.blob.core.windows.net/asset-064ed2d5-e42d-4c49-98eb-a712db5c614f?st=2012-12-26T23%3A04%3A22Z&se=2013-01-05T23%3A04%3A22Z&sr=c&si=9350bd2f-ec23-40b2-b27a-248bba01b97e&sig=oGgesnr8mXjCdTM5Dz%2FQpFRBDR0g0%2F60ECoXY14EvsA%3DBigBuckBunny.ism/manifest
Its not working .
When I paste this url on browser directly ,I get following error
AuthenticationFailedServer failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:154422cf-822e-4bbc-af2a-fa69273dfb89 Time:2012-12-27T08:57:30.9509847ZSignature fields not well formed.
But if I go and publish asset from portal( www.manage.windowsazure.com )--
I get like following url on protal..
http://mediaervices.origin.mediaservices.windows.net/5edbeae7-c3e6-45c5-bc5c-70f46b526cb5/BigBuckBunny.ism/Manifest
And it works with my silverlight player..
Now problem is that I am not getting url which starts with http from code and the url starting with https is not working with my player.
I guessed that its security issue and tried to host my player in winows azure and tried to player there but no success.
No, not a security issue. You are requesting a SAS url for a Smooth asset, you need an Origin URL. The correct code snippet is here, on my blog:
http://blog-ndrouin.azurewebsites.net/?p=1931
Specifically:
private static string GetStreamingUrl(CloudMediaContext context, string outputAssetId)
{
var daysForWhichStreamingUrlIsActive = 365;
var outputAsset = context.Assets.Where(a => a.Id == outputAssetId).FirstOrDefault();
var accessPolicy = context.AccessPolicies.Create(outputAsset.Name, TimeSpan.FromDays(daysForWhichStreamingUrlIsActive), AccessPermissions.Read | AccessPermissions.List);
var assetFiles = outputAsset.AssetFiles.ToList();
var assetFile = assetFiles.Where(f => f.Name.ToLower().EndsWith("m3u8-aapl.ism")).FirstOrDefault();
if (assetFile != null)
{
var locator = context.Locators.CreateLocator(LocatorType.OnDemandOrigin, outputAsset, accessPolicy);
Uri hlsUri = new Uri(locator.Path + assetFile.Name + "/manifest(format=m3u8-aapl)");
return hlsUri.ToString();
}
assetFile = assetFiles.Where(f => f.Name.ToLower().EndsWith(".ism")).FirstOrDefault();
if (assetFile != null)
{
var locator = context.Locators.CreateLocator(LocatorType.OnDemandOrigin, outputAsset, accessPolicy);
Uri smoothUri = new Uri(locator.Path + assetFile.Name + "/manifest");
return smoothUri.ToString();
}
assetFile = assetFiles.Where(f => f.Name.ToLower().EndsWith(".mp4")).FirstOrDefault();
if (assetFile != null)
{
var locator = context.Locators.CreateLocator(LocatorType.Sas, outputAsset, accessPolicy);
var mp4Uri = new UriBuilder(locator.Path);
mp4Uri.Path += "/" + assetFile.Name;
return mp4Uri.ToString();
}
return string.Empty;
}
as far as I know we can not call the javascript method in controller's action method. but how to consider that a particular code line get executed ? As i asked earlier here
we must have to get acknowledgment that line number so and so get executed. see this action in my controller
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult uploadfile(FormCollection fc)
{
UserMaster objUMaster = objAM.GetUser(new Guid(fc["userIdForFile"].ToString()));
try
{
string imagename = "";
//Check for files uploaded here.
foreach (string inputTagName in Request.Files)
{
HttpPostedFileBase file = Request.Files[inputTagName];
imagename = objUMaster.UserId.ToString() + file.FileName;
if (file.ContentLength > 0)
{
string filePath = Path.Combine(HttpContext.Server.MapPath("../Content/UserUploads"), objUMaster.UserId.ToString() + Path.GetFileName(file.FileName));
file.SaveAs(filePath);
string filePathThumb = Path.Combine(HttpContext.Server.MapPath("../Content/UserUploads/Thumbnails"), objUMaster.UserId.ToString() + Path.GetFileName(file.FileName));
var fl = Request.Files.Get(inputTagName);
Stream strm = fl.InputStream;
Image img = Image.FromStream(strm);
ResizeAndSaveHighQualityImage(img, 120, 120, filePathThumb, 100);
}
}
objUMaster.ProfilePhoto = imagename;
objAM.Save();
return RedirectToAction("EditProfile", new { id = objUMaster.UserId });
}
catch (Exception ex)
{
//SendEmail(ex.Message);
string strPath = HttpContext.Server.MapPath("../Content/UserUploads");
StreamWriter SW;
SW = System.IO.File.CreateText(strPath+"/log.txt");
SW.WriteLine(ex.Message.ToString());
SW.Close();
return RedirectToAction("EditProfile", new { id = objUMaster.UserId });
}
}
Here I am trying to upload the image in my domains file system (dir). but I want get alert so that I can confirm , this lie get executed successfully. because nothing happening as expected from this action. so can we call Javascript's "alert", or something else remedy?
Some pointers to help you:
See if Network service/account under which your application is running has permission on the location where you are saving your file.
Besides this to make sure that your file is saved, after save call you can make another call File.IsExist. If it exists then you can log the success/failure in some log file. Wouldn't that work for you?