I have a java servlet that serves files from s3. These files can be either image, pdf or doc/docx. I have to implement a feature in my web application to display these files in google doc viewer.
In my case, I am not able to send content so that google doc viewer reads it and displays the file. (when shouldDownload == Binary.YES).
This the code I have that downloads the file from s3 and set it in my bean class -
ApplicantzFileModel document = (ApplicantzFileModel) MongoSelectRogueModel
.selectOneById(ApplicantzFileModel.class, id);
Binary shouldDownload = Binary.valueOf(download);
if (document != null) {
if (shouldDownload == Binary.YES) {
docBean.fileStream = document.downloadFileStream();
docBean.fileName = document.getFileName();
docBean.isFileDownloadResponse = true;
} else {
File file = document.downloadFile();
if (file != null) {
String content = null;
content = FileHandler.read(file);
if (content != null) {
docBean.fileContent = content;
docBean.fileName = document.getFileName();
}
}
}
docBean.actionSuccess = true;
docBean.isFileContentResponse = true;
}
This is the code in my doGet/doPost to serve the response -
if (bean.isFileDownloadResponse) {
OutputStream responseOutputStream;
try {
response.setContentType("application/octet-stream");
response.addHeader("Content-disposition", "inline; filename=" + bean.fileName);
responseOutputStream = response.getOutputStream();
byte[] buf = new byte[4096];
int len = -1;
while ((len = bean.fileStream.read(buf)) != -1) {
responseOutputStream.write(buf, 0, len);
}
responseOutputStream.flush();
responseOutputStream.close();
bean.fileStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
} else {
response.setContentType("application/msword");
response.addHeader("Content-disposition", "inline; filename=" + bean.fileName);
responseStr = bean.fileContent;
PrintWriter writer = null;
try {
writer = response.getWriter();
} catch (IOException e) {
e.printStackTrace();
}
if (writer != null) {
writer.println(responseStr);
writer.flush();
writer.close();
}
}
And this is the html code in my frontend to open google doc viewer in fancybox -
"<a data-fancybox="" data-type="iframe" data-src="http://docs.google.com/viewer?url=http%3A%2F%2Fsomeserver.com%2Fapplication%2Fdocument%3Faction%3Dget%26id%3Dsomeid%26download%3DYES&embedded=true" href="javascript:void(0);" data-doc-id="someid">My Link</a>"
Or more specifically, google doc viewer url that opens up -
var innerurl = encodeURIComponent('http://someserver.com/application/document?action=get&id='+this.docId+'&download=YES');
this.docUrl = 'http://docs.google.com/viewer?url='+innerurl+'&embedded=true';
I am not able to open the word or pdf document in my fancybox. Can someone please suggest what to do to serve files via Java.
Related
I have written a code to open gallery and choose image file in CodenameOne. On iOS it also allows to capture image. When I capture a photo on iOS, the photo is rotated by 90°. When I pick photo from gallery it is not rotated. How to fix that 90° rotation? Here is my code for opening gallery:
Display.getInstance().openGallery((evt) -> {
if (evt != null && evt.getSource() != null) {
String filePath = (String) evt.getSource();
Image img = null;
try {
img = Image.createImage(filePath);
} catch (IOException e) {
}
if (img != null) {
img = img.scaledLargerRatio(IMAGE_WIDTH_FOR_UPLOAD, IMAGE_HEIGHT_FOR_UPLOAD);
ImageHelper.saveToFileSystem("image" + ".jpg", img, null, null);
base64Img = (String) ImageHelper.loadBase64FromFileSystem("image" + ".jpg");
browser.execute("document.getElementById(\"" + QR_PHOTO_UPLOAD_IMG_ID + "\").setAttribute('src', '" + BASE64_PREFIX + base64Img + "');"
+ " document.getElementById(\"" + QR_PHOTO_UPLOAD_INPUT_ID + "\").setAttribute('base64', '" + BASE64_PREFIX + base64Img + "');"
+ "");
}
}
photoGalleryOpened = false;
}, Display.GALLERY_IMAGE);
Here is code for Image saving to file system:
public static boolean saveToFileSystem(String path, Image capturedImage, String format, Float quality) {
if (format == null) {
format = ImageIO.FORMAT_JPEG;
}
if (quality == null) {
quality = 1f;
}
OutputStream os = null;
try {
String pathToBeStored = path.startsWith(APPHOMEPATH)? path : (APPHOMEPATH + path);
os = FileSystemStorage.getInstance().openOutputStream(pathToBeStored);
ImageIO.getImageIO().save(capturedImage, os, format, quality);
os.close();
} catch (Exception e) {
Log.e(e);
try {
if (os != null) {
os.close();
}
} catch (IOException ex) {
Log.e(ex);
}
return false;
} finally {
try {
if (os != null) {
os.close();
}
} catch (IOException ex) {
Log.p(ex.getMessage());
}
}
return true;
}
Here is code for getting base64 string from image file:
public static Object loadBase64FromFileSystem(String path) {
String ret = "";
try {
Image image = loadFromFileSystem(path);
if (image == null) {
throw new IOException("File not found (" + APPHOMEPATH + path + ")");
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.getImageIO().save(image, baos, ImageIO.FORMAT_JPEG, 1);
byte[] bytes = baos.toByteArray();
ret = Base64.encodeNoNewline(bytes);
} catch (Exception ex) {
Log.e(ex);
}
return ret;
}
public static Image loadFromFileSystem(String path) {
try {
File f = new File(APPHOMEPATH + path);
if(f.exists()){
Log.p("Image exists: " + f.exists());
Image img = Image.createImage(f.getPath());
return img;
}else{
Log.p("Image doesn't exist");
return null;
}
} catch (Exception ex) {
Log.e(ex);
}
Log.p("Image doesn't exist");
return null;
}
Mobile OS's often take a photo with one orientation and then just mark it as rotated in a tag e.g. photos are always landscape but when you take a portrait mode photo it's marked as rotated by 90 degrees.
This works fine as most apps read the tags and implicitly rotate that photo after loading. Some apps don't and the native image reading code doesn't do that on mobile OSs. We need to explicitly parse the tags and do the rotation. We do that for capture logic but we don't do that generically for image loading.
The problem is that rotating the image is very expensive and doing it for every image load would be expensive (but might be what we have to do in this case). Right now the only workaround I can think about is manually parsing the image tags which would be a bit painful.
I need help in fetching file path of contents that we pick from downloads folder or any other folder through Intent.
I am attaching a fileUtil class that I have been using and it works well till Nougat version. But with oreo and that too in some specific devices, we receive a null path in return. So if anyone has faced such an error and found a solution to this, then please share here.
if(resultCode ==RESULT_OK)
{
final Uri uri = data.getData();
// Get the File path from the Uri
String path = FileUtils.getPath(this, uri);
// Alternatively, use FileUtils.getFile(Context, Uri)
if (path != null && FileUtils.isLocal(path)) {
//File file = new File(path);
this.file = new File(path);
profile_imagepath = path;
filename = file.getName();
txtselectedfile.setText(filename);
}
}
You can try to use ACTION_PICK for api level above 26 to get this issue fixed, instead of using ACTION_GET_CONTENT.
Try and hope this helps you.
1) Open file intent.
Intent intent = new Intent()
.setType("*/*")
.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(Intent.createChooser(intent, "Select a file"), REQUEST_CODE);
2)get download document path using below method.
if (isDownloadsDocument(uri)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final String id;
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DISPLAY_NAME}, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
String fileName = cursor.getString(0);
String path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName;
if (!TextUtils.isEmpty(path)) {
return path;
}
}
} finally {
if (cursor != null)
cursor.close();
}
id = DocumentsContract.getDocumentId(uri);
if (!TextUtils.isEmpty(id)) {
if (id.startsWith("raw:")) {
return id.replaceFirst("raw:", "");
}
String[] contentUriPrefixesToTry = new String[]{
"content://downloads/public_downloads",
"content://downloads/my_downloads"
};
for (String contentUriPrefix : contentUriPrefixesToTry) {
try {
final Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
/* final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));*/
return getDataColumn(context, contentUri, null, null);
} catch (NumberFormatException e) {
//In Android 8 and Android P the id is not a number
return uri.getPath().replaceFirst("^/document/raw:", "").replaceFirst("^raw:", "");
}
}
}
} else {
final String id = DocumentsContract.getDocumentId(uri);
final boolean isOreo = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
if (id.startsWith("raw:")) {
return id.replaceFirst("raw:", "");
}
try {
contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
} catch (NumberFormatException e) {
e.printStackTrace();
}
if (contentUri != null) {
return getDataColumn(context, contentUri, null, null);
}
}
}
I am new to Google Drive and have following scenarios for which I am not able to find anything (not sure if anything exists or not)
–> I am creating a Windows app which will be SAAS based. Different Users will register and create their company logins and subusers under them. Now I want them to put the google drive credentials in one of the form and this should work for rest of the users. Currently the problem is that while development I got the google log in done and it never asks for the login again but when testing on a different system with different login, it keeps asking for google login. I simply want admin users to put their google drive credentials and it should work for upload and download files for all the users for that company.
–> I want to keep versions of the same file (just like google drive does by default) on google drive. Lets say user A uploaded file xyz and then user B downloaded and changed file xyz and uploaded it on the drive again.
I want 2 things here – only the changed content should get uploaded and not the whole file (this will save time for the user)
2ndly I want to have history of the same file so I can show in my Windows application
#region Get Service Object
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "GoogleDriveClientID",
ClientSecret = "GoogleDriveClientSecret"
},
new[] { DriveService.Scope.Drive }, "user", CancellationToken.None).Result;
// Create the service.
service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "AppName",
});
#endregion
#region Uploading
public void uploadOnGoogleDrive(ObservableCollection<JobAttachments> AttachmentsColl, bool IsDocSaved)
{
try
{
service = getServiceObject();
List<Google.Apis.Drive.v2.Data.File> fileList = retrieveAllFiles(service);
List<Google.Apis.Drive.v2.Data.File> directoryList = GetDirectoryList(service);
if (IsDocSaved)
{
#region for checking if the file already exists
foreach (Google.Apis.Drive.v2.Data.File item in fileList)
{
foreach (JobAttachments attach in AttachmentsColl)
{
if (item.Title == attach.AttachmtGUID)
{
MessageBoxResult result = System.Windows.MessageBox.Show(LogMessages.GetResourceMessage(LogMessages.MessageEnumeration.GD_AlreadyExistsMsg), "Confirmation", MessageBoxButton.YesNoCancel);
if (result == MessageBoxResult.Yes)
{
//DeleteFile(service, item);
Google.Apis.Drive.v2.Data.File body = new Google.Apis.Drive.v2.Data.File();
body.Title = attach.AttachmtGUID;
body.MimeType = item.MimeType;
fileSize = body.FileSize;
byte[] byteArray = System.IO.File.ReadAllBytes(attach.AttachmentName);
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
FilesResource.UpdateMediaUpload request = service.Files.Update(body, item.Id, stream, item.MimeType);
request.Upload();
}
else
{
return;
}
break;
}
}
}
#endregion
}
else
{
#region for direct uploading on google drive
if (AttachmentsCollection != null && AttachmentsCollection.Count > 0)
{
string folderID = string.Empty;
if (_IsProject)
{
if (directoryList != null && directoryList.Count > 0)
{
foreach (var dir in directoryList)
{
if (dir.Title.Equals(_ProjectName))
{
folderID = dir.Id;
break;
}
}
}
if (string.IsNullOrEmpty(folderID))
{
Google.Apis.Drive.v2.Data.File foldbody = new Google.Apis.Drive.v2.Data.File();
foldbody.Title = _ProjectName;
foldbody.MimeType = "application/vnd.google-apps.folder";
foldbody.Parents = new List<ParentReference>() { new ParentReference() { Id = "root" } };
Google.Apis.Drive.v2.Data.File file = service.Files.Insert(foldbody).Execute();
folderID = file.Id;
}
}
else
{
//project folder
string prjFolder = string.Empty;
string tskFolder = string.Empty;
Google.Apis.Drive.v2.Data.File foldbody;
if (directoryList != null && directoryList.Count > 0)
{
foreach (var dir in directoryList)
{
if (dir.Title.Equals(_ProjectName))
{
prjFolder = dir.Id;
break;
}
}
}
if (string.IsNullOrEmpty(prjFolder))
{
foldbody = new Google.Apis.Drive.v2.Data.File();
foldbody.Title = _ProjectName;
foldbody.MimeType = "application/vnd.google-apps.folder";
foldbody.Parents = new List<ParentReference>() { new ParentReference() { Id = "root" } };
Google.Apis.Drive.v2.Data.File file = service.Files.Insert(foldbody).Execute();
prjFolder = file.Id;
}
//task folder
if (directoryList != null && directoryList.Count > 0)
{
foreach (var dir in directoryList)
{
if (dir.Title.Equals(_TaskName) && dir.Parents[0].Id.Equals(prjFolder))
{
folderID = dir.Id;
break;
}
}
}
if (string.IsNullOrWhiteSpace(folderID))
{
foldbody = new Google.Apis.Drive.v2.Data.File();
foldbody.Title = _TaskName;
foldbody.MimeType = "application/vnd.google-apps.folder";
foldbody.Parents = new List<ParentReference>() { new ParentReference() { Id = prjFolder } };
Google.Apis.Drive.v2.Data.File file1 = service.Files.Insert(foldbody).Execute();
folderID = file1.Id;
}
}
foreach (JobAttachments item in AttachmentsColl)
{
if (!string.IsNullOrEmpty(item.AttachmentName))
{
Google.Apis.Drive.v2.Data.File body = new Google.Apis.Drive.v2.Data.File();
body.Title = item.AttachmtGUID;
body.MimeType = item.MimeType;
body.Parents = new List<ParentReference>() { new ParentReference() { Id = folderID } };
//fileSize = body.FileSize;
byte[] byteArray = System.IO.File.ReadAllBytes(item.AttachmentName);
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, item.MimeType);
request.Upload();
}
}
}
#endregion
}
}
catch (Exception ex)
{
if (ex.InnerException != null)
throw ex.InnerException;
}
}
#endregion
#region Download File
private async Task DownloadFile(DriveService service, string url, string title, long? fSize)
{
service = getServiceObject();
var downloader = new MediaDownloader(service);
//downloader.ChunkSize = 256 * 1024;
downloader.ProgressChanged += Download_ProgressChanged;
var fileName = string.Empty;
//for downloading on system
var SaveFileDialog = new SaveFileDialog();
SaveFileDialog.Title = "Save As";
SaveFileDialog.FileName = title;
Nullable<bool> result = SaveFileDialog.ShowDialog();
if (result == true)
fileName = SaveFileDialog.FileName;
else if (result == false)
{
prgrsBar.StyleSettings = new ProgressBarStyleSettings();
prgrsBar.Value = 0;
return;
}
else
{
if (Directory.Exists(#"\Downloads"))
fileName = #"\Downloads\" + title;
}
if (!string.IsNullOrWhiteSpace(fileName))
using (var fileStream = new System.IO.FileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
fileSize = fSize;
var progress = await downloader.DownloadAsync(url, fileStream);
if (progress.Status.ToString() == DownloadStatus.Completed.ToString())
{
fName = fileStream.Name;
prgrsBar.StyleSettings = new ProgressBarStyleSettings();
prgrsBar.Value = 0;
fileStream.Flush();
}
if (progress.Status.ToString() == DownloadStatus.Failed.ToString())
{
HandleDocuments.IsEditButtonClicked = false;
MessageBox.Show("Failed......." + progress.Exception.Message);
}
}
}
#endregion
#region Delete File
private Task DeleteFile(DriveService service, Google.Apis.Drive.v2.Data.File file)
{
service = getServiceObject(); //comment this if calling from another function; create the service object in that function and pass it as parameter to this function.
service.Files.Delete(file.Id).ExecuteAsync();
service.Files.EmptyTrash();
return null;
}
#endregion
#region Get all Directories and Files from Google Drive
public List<Google.Apis.Drive.v2.Data.File> GetDirectoryList(DriveService service)
{
//Creating the global list
List<Google.Apis.Drive.v2.Data.File> AllDirectories = new List<Google.Apis.Drive.v2.Data.File>();
//setting up the Request.
FilesResource.ListRequest request = service.Files.List();
//MaxResults: How many we want back at a time max is 1000
request.MaxResults = 1000;
//Q: Search results. all i want are folders that havent been trashed (deleted)
request.Q = "mimeType='application/vnd.google-apps.folder' and trashed=false";
do
{
try
{
// getting the results
FileList files = request.Execute();
// adding the results to the list.
AllDirectories.AddRange(files.Items);
// If there are more results then your MaxResults you will have a nextPageToken to get the rest of the results.
request.PageToken = files.NextPageToken;
}
catch (Exception ex)
{
request.PageToken = null;
if (ex.InnerException != null)
throw ex.InnerException;
}
} while (!String.IsNullOrEmpty(request.PageToken));
List<Google.Apis.Drive.v2.Data.File> DirsInRoot = AllDirectories.Where(a => (a.Parents.Count > 0 && a.Parents.FirstOrDefault().IsRoot.HasValue) ? a.Parents.FirstOrDefault().IsRoot.Value : false).ToList<Google.Apis.Drive.v2.Data.File>();
List<string> HirearcyList = new List<string>();
// The first Dir is Root it doesnt get returned. But we need it if we
// Want to be able to list the files that are in the root dir.
HirearcyList.Add("Root");
// recersive magic here.
foreach (Google.Apis.Drive.v2.Data.File myDir in DirsInRoot)
{
HirearcyList.Add(" " + myDir.Title);
HirearcyList.AddRange(RecsiveDir(AllDirectories, myDir.Id, " "));
}
return AllDirectories;
}
public List<String> RecsiveDir(List<Google.Apis.Drive.v2.Data.File> allDirs, string ParentId, string Prefix)
{
List<string> result = new List<string>();
List<Google.Apis.Drive.v2.Data.File> DirsInParentId = allDirs.Where(a => (a.Parents.Count > 0 && a.Parents.FirstOrDefault().IsRoot.HasValue) ? a.Parents.FirstOrDefault().Id == ParentId : false).ToList<Google.Apis.Drive.v2.Data.File>();
foreach (Google.Apis.Drive.v2.Data.File myDir in DirsInParentId)
{
result.Add(Prefix + myDir.Title);
result.AddRange(RecsiveDir(allDirs, myDir.Id, Prefix + " "));
}
return result;
}
public static List<Google.Apis.Drive.v2.Data.File> retrieveAllFiles(DriveService service)
{
List<Google.Apis.Drive.v2.Data.File> result = new List<Google.Apis.Drive.v2.Data.File>();
FilesResource.ListRequest request = service.Files.List();
request.MaxResults = 1000;
do
{
try
{
FileList files = request.Execute();
result.AddRange(files.Items);
request.PageToken = files.NextPageToken;
//service.Revisions.List(files.Items[0].Id) // for getting the file Revision history
}
catch (Exception ex)
{
request.PageToken = null;
if (ex.InnerException != null)
throw ex.InnerException;
}
} while (!String.IsNullOrEmpty(request.PageToken));
return result;
}
#endregion
Thanks
Jatinder
I want to download a file stored in system directory but when downloading the file in jsf page I get it empty.
This is my xhtml page :
<h:form>
<h:commandButton value="Download" action="#{helloBean.downloadFile}" />
</h:form>
and my managed bean :
#ManagedBean
#SessionScoped
public class HelloBean {
public void downloadFile() {
File file = new File("C:\\data\\contacts.doc");
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
response.setHeader("Content-Disposition", "attachment;filename=contacts.doc");
response.setContentLength((int) file.length());
ServletOutputStream out = null;
try {
FileInputStream input = new FileInputStream(file);
byte[] buffer = new byte[1024];
out = response.getOutputStream();
int i = 0;
while ((i = input.read(buffer)) != -1) {
out.write(buffer);
out.flush();
}
FacesContext.getCurrentInstance().getResponseComplete();
} catch (IOException err) {
err.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException err) {
err.printStackTrace();
}
}
}
}
so How to solve it? Thanks in advance.
I think this code solve your problem.
public void download() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) context
.getExternalContext().getResponse();
File file = new File(filePath);
if (!file.exists()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType("application/octet-stream");
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment;filename=\""
+ file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new FileInputStream(file),
DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(),
DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
input.close();
output.close();
}
context.responseComplete();
}
Currently attachment takes stream for the content, is it possible to set a youtube video url for the attachment?
Thanks
This is not yet possible with the current version of the API and Glass client. Feel free to file a feature request on our issues tracker.
It is possible to stream a youtube video in the timeline card, here is the C#.Net code. use this name space "YoutubeExtractor".This works fine for me. When getting the youtube video url get the link that comes after you select share.
private static String InsertItem5(MainController controller)
{
string link = "http://youtu.be/9uYKISlL7Vg";
IEnumerable<VideoInfo> videoInfos = DownloadUrlResolver.GetDownloadUrls(link);
VideoInfo video = videoInfos.First(info => info.VideoType == VideoType.Mp4 && info.Resolution == 360);
String vLink = video.DownloadUrl;
TimelineItem critical = new TimelineItem()
{
Text = "Menu Card",
BundleId = "666",
Notification = new NotificationConfig() { Level = "DEFAULT" },
MenuItems = new List<MenuItem>()
{
new MenuItem() {Action = "DELETE"},
}
};
String mediaLink = vLink;
if (!String.IsNullOrEmpty(mediaLink))
{
Stream stream = null;
if (mediaLink.StartsWith("/"))
{
stream = new StreamReader(controller.Server.MapPath(mediaLink)).BaseStream;
}
else
{
HttpWebRequest request = WebRequest.Create(mediaLink) as HttpWebRequest;
request.UseDefaultCredentials = false;
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);
}
}
controller.Service.Timeline.Insert(critical, stream, "video/mp4").Upload();
}
else
{
controller.Service.Timeline.Insert(critical).Fetch();
}