Streaming mp4 videos from serversocket on AIR - ios

I am trying to build a mini-webserver on an iPad inside an Adobe AIR application.
I am using the ServerSocket class to set up the webserver as shown by example at http://coenraets.org/blog/2010/07/creating-a-web-server-using-the-new-server-socket-api-in-air-2/.
I am trying to extend this by allowing the webserver to serve mp4 video files.
I have added the mimetype: mimeTypes[".mp4"] = "video/mp4";
but serving an mp4 to be played in a browser is not exactly the same as providing a html file.
Anyone can point me in the right direction for this? This is the code I currently have when the socket is responding:
private function webserverConnectionSocketDataHandler(evt:ProgressEvent):void{
try
{
var socket:Socket = evt.target as Socket;
var bytes:ByteArray = new ByteArray();
socket.readBytes(bytes);
var request:String = "" + bytes;
var filePath:String = request.substring(5, request.indexOf("HTTP/") - 1);
var file:File = File.applicationDirectory.resolvePath("AppStorage").resolvePath(filePath);
if (file.exists && !file.isDirectory)
{
//Range: bytes=0-131726
var offset:uint = 0;
var bytesRequested:uint = 0;
if(request.indexOf("Range: bytes=") >= 0){
offset = uint(request.split("Range: bytes=")[1].split("-")[0]);
bytesRequested = (request.split("Range: bytes=")[1].split("-")[1]);
}
if(bytesRequested == 0) bytesRequested = file.size;
var stream:FileStream = new FileStream();
stream.open( file, FileMode.READ );
var content:ByteArray = new ByteArray();
stream.readBytes(content, offset, bytesRequested);
stream.close();
if(bytesRequested != file.size){
socket.writeUTFBytes("HTTP/1.1 206 Partial Content\n");
socket.writeUTFBytes("Content-Type: " + getMimeType(filePath) + "\n\n");
socket.writeUTFBytes("Content-Range: " + offset + "-" + bytesRequested + "/" + file.size + "\n\n");
socket.writeUTFBytes("Content-Length: " + (bytesRequested-offset) + "\n\n");
socket.writeUTFBytes("Date: " + new Date().toLocaleTimeString() + "\n\n");
}else{
socket.writeUTFBytes("HTTP/1.1 200 OK\n");
socket.writeUTFBytes("Content-Type: " + getMimeType(filePath) + "\n\n");
socket.writeUTFBytes("Content-Length: " + file.size + "\n\n");
}
socket.writeBytes(content);
}
else
{
socket.writeUTFBytes("HTTP/1.1 404 Not Found\n");
socket.writeUTFBytes("Content-Type: text/html\n\n");
socket.writeUTFBytes("<html><body><h2>Page Not Found</h2></body></html>");
}
socket.flush();
socket.close();
}
catch (error:Error)
{
trace(error.message, "Error");
}
}
But that is not really working as expected. The goal is to be able to view an mp4 from inside my iPad application's AppStorage directory from inside my browser on PC. It works for html files, not for mp4.

Related

Changing synchronous call to async await(Asynchronous ) MvC controller

I am new to C# Asp.net mvc asynchronous programming. I need to uplaod vidoe to my server but it video upload is locked when I uploading the video. I can not do another tasks in parallel. I have tried like this but it is not working.
public async Task<ActionResult> upload()
{
if (Request.Files.Count > 0)
{
int chunk = Request["chunk"] != null ?
int.Parse(Request["chunk"]) : 0;
string fileName = Request["name"] != null ? Request["name"] :
string.Empty;
string upath = "";
if (Request.Headers["UName"] != null)
upath = Request.Headers["UName"].ToString();
//if (CloudSettings.EnableCloudStorage && upath != "")
// _fileName = upath.Substring(0, 3) + "-" + _fileName; // void duplication in cloud storage
long AlbumID = 0;
if (Request.Headers["MediaID"] != null)
AlbumID = Convert.ToInt64(Request.Headers["MediaID"]);
string uploadPath = "";
// default path
if (upath == "")
uploadPath = UrlConfig.Published_Video_Path(); // direct upload to published area
else
uploadPath = UrlConfig.Published_Video_Path(upath); // source video path
FileStream fs;
using (fs = new FileStream(Path.Combine(uploadPath, fileName), chunk == 0 ? FileMode.Create : FileMode.Append))
{
byte[] buffer = new byte[Request.Files[0].InputStream.Length];
await Request.Files[0].InputStream.ReadAsync(buffer, 0, buffer.Length);
await fs.WriteAsync(buffer, 0, buffer.Length);
}
string url = "";
string filetype = System.IO.Path.GetExtension(fileName);
string fileIndex = fileName.Replace(filetype, "");
string elementid = UtilityBLL.ReplaceSpaceWithHyphin(fileIndex);
//eturn fileName; // "Success";
return this.Content("{\"jsonrpc\" : \"2.0\", \"result\" : \"OK\", \"id\" : \"id\", \"fname\" : \"" + fileName + "\", \"url\" : \"" + url + "\", \"filetype\" : \"" + filetype + "\", \"filename\" : \"" + fileName + "\", \"fileIndex\" : \"" + fileIndex + "\", \"eleid\" : \"" + elementid + "\"}", "text/plain");
}
else
{
return this.Content("failed", "text/plain");
}
}

File Read-Write Error in iOS

I have used following code for file reading and writing.
private void StorePuzzleData ()
{
FileInfo fileInfo = new FileInfo (Application.persistentDataPath + "\\" + difficultyLevel + puzzleId + ".txt");
if (fileInfo.Exists)
fileInfo.Delete ();
string fileData = string.Empty;
foreach (CellInformation cellInfo in cellInfoList)
fileData += cellInfo.RowIndex + "#" + cellInfo.ColIndex + "#" + cellInfo.number + "#" + cellInfo.CellColor + "#" + cellInfo.CellDisplayColor + "#" + (cellInfo.IsGroupComplete ? 1 : 0) + ",";
StreamWriter streamWriter = fileInfo.CreateText ();
streamWriter.WriteLine (fileData);
streamWriter.Close ();
DataStorage.StorePuzzleTimePassed (difficultyLevel, puzzleId, GameController.gamePlayTime);
}
private void ReadPuzzleData ()
{
// format: rownumber, colnumber, number, cellcolor, celldisplaycolor, isgroupcomplete
StreamReader streamReader = File.OpenText (Application.persistentDataPath + "\\" + difficultyLevel + puzzleId + ".txt");
string fileData = streamReader.ReadLine ();
}
But I am getting following error in actual iOS device running. This code working correct in iMac as well in android device.
Please give me some suggestion what changes I need to do to make this correct.
It seems you're using Windows-style paths in a Unix-like (Apple Mac OS) environment. Notice that on windows you have paths with a backslash like
C:\Users\Maxi\Desktop
On Unix-like system however something like
/var/mobile/Containers
You notice that in your faulty path you have mixed forward and backward slashes, which makes the path invalid.
/var/mobile/Containers/Data/Application/2.....\debutan1.txt
The correct way to always generate the correct path is to use the Path.Combine(string, string) function. This will combine two paths using the correct directory path seperator, which can also be seperatly accessed through Path.DirectorySeparatorChar.
So, in order to make your code correct, you would do
using System.IO; /* must be imported */
private void StorePuzzleData ()
{
FileInfo fileInfo = new FileInfo (Path.Combine(Application.persistentDataPath, difficultyLevel + puzzleId + ".txt"));
if (fileInfo.Exists)
fileInfo.Delete ();
string fileData = string.Empty;
foreach (CellInformation cellInfo in cellInfoList)
fileData += cellInfo.RowIndex + "#" + cellInfo.ColIndex + "#" + cellInfo.number + "#" + cellInfo.CellColor + "#" + cellInfo.CellDisplayColor + "#" + (cellInfo.IsGroupComplete ? 1 : 0) + ",";
StreamWriter streamWriter = fileInfo.CreateText ();
streamWriter.WriteLine (fileData);
streamWriter.Close ();
DataStorage.StorePuzzleTimePassed (difficultyLevel, puzzleId, GameController.gamePlayTime);
}
private void ReadPuzzleData ()
{
// format: rownumber, colnumber, number, cellcolor, celldisplaycolor, isgroupcomplete
StreamReader streamReader = File.OpenText (Path.Combine(Application.persistentDataPath, difficultyLevel + puzzleId + ".txt"));
string fileData = streamReader.ReadLine ();
}
If this still gives an "Access denied" error it must be because of filepermissions. Post the output of ls -la <thatpath> then.

How to upload powerpoint file to server phonegap?

Hello I Want to upload a powerpoint file using phonegap file transfer protocol to my local java server thru ios simulator, the location of the file on the phone is passed to the handleOpenURL function when the user selects to open a powerpoint with my app. The problem is that nothing is happening although im sure this method is executing??!! can anyone help please?
function handleOpenURL(url)
{
setTimeout(function() {
alert(url);
jQuery.get( "http://192.168.1.100:8080/PpServer/getnumberofslides" , function( data ) {
numberofslides=data;
alert( "Load was performed." + data );
});
fileURL = url;
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
// processapplication();
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
var uri = encodeURI("http://192.168.1.100:8080/NewServerlet");
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=fileURL.substr(fileURL.lastIndexOf('/')+1);
options.mimeType="multipart/form-data";
options.httpMethod="Post"
// options.params = {"file"};
var headers={'headerParam':'file'};
// options.headers = headers;
var ft = new FileTransfer();
ft.onprogress = function(progressEvent) {
if (progressEvent.lengthComputable) {
loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);
} else {
loadingStatus.increment();
}
};
ft.upload(fileURL, uri, win, fail, options);
}, 0);
//
}

firefox extension working on page load

I'm trying to create my first extension.
I've found this sample: http://blog.mozilla.org/addons/2009/01/28/how-to-develop-a-firefox-extension/
I need to get some html content on a specific page and write something in the same page, so I modified it and got what I needed (with javascript I added content in the table I want). But to view my content I have to launch the extension from the button on the status bar, while I would like to have it already active in the page as I load/reload it (with a check on the url so to have it working only on that page) but I can't have it automatically.
I tried to add linkTargetFinder.run(); on init area, but... nothing. Moreover the extension as an "autorun" but eve if active, I don0t see any change.
any working sample?
Thanks
Nadia
Here it is the code (I edited just the .js file), I commented a couple of test not working...
var linkTargetFinder = function () {
var prefManager = Components.classes["#mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
return {
init : function () {
gBrowser.addEventListener("load", function () {
var autoRun = prefManager.getBoolPref("extensions.linktargetfinder.autorun");
if (autoRun) {
linkTargetFinder.run();
}
//linkTargetFinder.run(); // doesn't work
}, false);
//linkTargetFinder.run(); // doesn't work
alert("ZZZZZZZZZZZZZZZZZZ"); // doesn't work
},
run : function () {
var head = content.document.getElementsByTagName("head")[0],
style = content.document.getElementById("link-target-finder-style"),
allLinks = content.document.getElementsByTagName("a"),
foundLinks = 0;
if (!style) {
style = content.document.createElement("link");
style.id = "link-target-finder-style";
style.type = "text/css";
style.rel = "stylesheet";
style.href = "chrome://linktargetfinder/skin/skin.css";
head.appendChild(style);
}
for (var i=0, il=allLinks.length; i<il; i++) {
elm = allLinks[i];
if (elm.getAttribute("target")) {
elm.className += ((elm.className.length > 0)? " " : "") + "link-target-finder-selected";
foundLinks++;
}
}
if (foundLinks === 0) {
alert("No links found with a target attribute");
}
else {
//alert("Found " + foundLinks + " links with a target attribute");
}
t = content.document.getElementById("ERSContainer"), // ID of the table
d = t.getElementsByTagName("tr")[1],
r = d.getElementsByTagName("td")[1];
var myMail = "mail: "+r.textContent; //ok scrive nella td
var myName = content.document.getElementById("buyercontactname").value;
var myAddr1 = content.document.getElementById("buyeraddress1").value;
var myAddr2 = content.document.getElementById("buyeraddress2").value;
var myCity = content.document.getElementById("buyercity").value;
var myProv = content.document.getElementById("buyerstateprovince").value;
var myCAP = content.document.getElementById("buyerzip").value;
var elt = content.document.getElementById("buyercountry");
var myCountry = elt.options[elt.selectedIndex].text;
var myTel = content.document.getElementById("dayphone1").value;
var myTag1 = "<tr><td colspan='2'>OK!!!<br />";
var myTag2 = "</td></tr>";
z= t.innerHTML;
t.innerHTML = myTag1 + myMail +
" - "+myName+
myAddr1 + "<br />" +
myAddr2 + "<br />" +
myCity + "<br />" +
myProv + "<br />" +
myCAP + "<br />" +
myCountry + "<br />" +
myTel + "<br />" +
myFlash+
myTag2+z;
}
};
}();
window.addEventListener("load", linkTargetFinder.init, false);
If what you are doing is running a bit of JavaScript on a specific web page, like adding content into a table, maybe you should consider doing a userscript for the Greasemonkey addon instead of a full addon. With this you write your JS for the page and it gets executed each time you browse this specific page.
edit:
Try with this :
init: function () {
gBrowser.addEventListener("load", linkTargetFinder.run, true);
},
...
I bet that the extensions.linktargetfinder.autorun does not exist. So getBoolPref throws an exception and the rest is history.
Change your code to the following
var autoRun;
try {
autoRun = prefManager.getBoolPref("extensions.linktargetfinder.autorun");
} catch(e){
autoRun = false;
}

"Authorization is required to perform that action" in Google Scripts with no way to give authorization

I am trying to create a sort of middleware so some legacy software I am working on can consume Twitter feeds.
Since Twitter has made API 1.0 obsolete and 1.1 requires OAuth and because for this project I only have client-side scripting available to me, I opted to use a Google script to perform the OAuth negotiation:
Source: http://www.labnol.org/internet/twitter-rss-feeds/27931/
function start() {
// Get your Twitter keys from dev.twitter.com
var CONSUMER_KEY = "-----";
var CONSUMER_SECRET = "----";
// Ignore everything after this line
initialize(CONSUMER_KEY, CONSUMER_SECRET);
}
function initialize(key, secret) {
ScriptProperties.setProperty("TWITTER_CONSUMER_KEY", key);
ScriptProperties.setProperty("TWITTER_CONSUMER_SECRET", secret);
var url = ScriptApp.getService().getUrl();
if (url) {
connectTwitter();
var msg = "";
msg += "Sample RSS Feeds for Twitter\n";
msg += "============================";
msg += "\n\nTwitter Timeline of user #labnol";
msg += "\n" + url + "?action=timeline&q=labnol";
msg += "\n\nTwitter Favorites of user #labnol";
msg += "\n" + url + "?action=favorites&q=labnol";
msg += "\n\nTwitter List labnol/friends-in-india";
msg += "\n" + url + "?action=list&q=labnol/friends-in-india";
msg += "\n\nTwitter Search for New York";
msg += "\n" + url + "?action=search&q=new+york";
msg += "\n\nYou should replace the value of 'q' parameter in the URLs as per requirement.";
msg += "\n\nFor help, please refer to http://www.labnol.org/?p=27931";
MailApp.sendEmail(Session.getActiveUser().getEmail(), "Twitter RSS Feeds", msg);
}
}
function doGet(e) {
var a = e.parameter.action;
var q = e.parameter.q;
var feed;
switch (a) {
case "timeline":
feed = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=" + q;
break;
case "search":
feed = "https://api.twitter.com/1.1/search/tweets.json?q=" + encodeString(q);
break;
case "favorites":
feed = "https://api.twitter.com/1.1/favorites/list.json?screen_name=" + q;
break;
case "list":
var i = q.split("/");
feed = "https://api.twitter.com/1.1/lists/statuses.json?slug=" + i[1] + "&owner_screen_name=" + i[0];
break;
default:
feed = "https://api.twitter.com/1.1/statuses/user_timeline.json";
break;
}
var id = Utilities.base64Encode(feed);
var cache = CacheService.getPublicCache();
var rss = cache.get(id);
if ((!rss) || (rss == "undefined")) {
rss = JSONtoRSS(feed, a, q);
cache.put(id, rss, 3600);
}
return ContentService.createTextOutput(rss)
.setMimeType(ContentService.MimeType.RSS);
}
function JSONtoRSS(json, type, key) {
oAuth();
var options = {
"method": "get",
"oAuthServiceName": "twitter",
"oAuthUseToken": "always"
};
try {
var result = UrlFetchApp.fetch(json, options);
if (result.getResponseCode() === 200) {
var tweets = Utilities.jsonParse(result.getContentText());
if (type == "search")
tweets = tweets.statuses;
if (tweets) {
var len = tweets.length;
var rss = "";
if (len) {
rss = '<?xml version="1.0"?><rss version="2.0">';
rss += ' <channel><title>Twitter ' + type + ': ' + key + '</title>';
rss += ' <link>' + htmlentities(json) + '</link>';
rss += ' <pubDate>' + new Date() + '</pubDate>';
for (var i = 0; i < len; i++) {
var sender = tweets[i].user.screen_name;
var tweet = htmlentities(tweets[i].text);
rss += "<item><title>" + sender + ": " + tweet + "</title>";
rss += " <author>" + tweets[i].user.name + " (#" + sender + ")</author>";
rss += " <pubDate>" + tweets[i].created_at + "</pubDate>";
rss += " <guid isPermaLink='false'>" + tweets[i].id_str + "</guid>";
rss += " <link>https://twitter.com/" + sender + "/statuses/" + tweets[i].id_str + "</link>";
rss += " <description>" + tweet + "</description>";
rss += "</item>";
}
rss += "</channel></rss>";
return rss;
}
}
}
} catch (e) {
Logger.log(e.toString());
}
}
function connectTwitter() {
oAuth();
var search = "https://api.twitter.com/1.1/application/rate_limit_status.json";
var options = {
"method": "get",
"oAuthServiceName": "twitter",
"oAuthUseToken": "always"
};
try {
var result = UrlFetchApp.fetch(search, options);
} catch (e) {
Logger.log(e.toString());
}
}
function encodeString(q) {
var str = encodeURIComponent(q);
str = str.replace(/!/g, '%21');
str = str.replace(/\*/g, '%2A');
str = str.replace(/\(/g, '%28');
str = str.replace(/\)/g, '%29');
str = str.replace(/'/g, '%27');
return str;
}
function htmlentities(str) {
str = str.replace(/&/g, "&");
str = str.replace(/>/g, ">");
str = str.replace(/</g, "<");
str = str.replace(/"/g, """);
str = str.replace(/'/g, "'");
return str;
}
function oAuth() {
var oauthConfig = UrlFetchApp.addOAuthService("twitter");
oauthConfig.setAccessTokenUrl("https://api.twitter.com/oauth/access_token");
oauthConfig.setRequestTokenUrl("https://api.twitter.com/oauth/request_token");
oauthConfig.setAuthorizationUrl("https://api.twitter.com/oauth/authorize");
oauthConfig.setConsumerKey(ScriptProperties.getProperty("TWITTER_CONSUMER_KEY"));
oauthConfig.setConsumerSecret(ScriptProperties.getProperty("TWITTER_CONSUMER_SECRET"));
}
I have followed all of the instructions prescribed in the guide including running 'start' twice... and all that does is send my email account an email with the various URLs. When I try to access the URLs provided in the email (and the plan is to drop that URL into our legacy javascript that currently points to the Twitter 1.0 API), i get the error "Authorization is required to perform that action"
I have confirmed countless times that it is set up to "Execute the app as [me]" and "Anyone, even anonymous can access app"
I am not sure what I am missing or what got screwed up.
Turns out, I forgot to set up the callback URL within the Twitter app setup as specified in the source instructions. Oops!
This would explain why it wasn't working even though everything on the Google side was correct.

Resources