I have downloaded this library into my project and put it into "lib" folder in my project.
Then I add it into the cotroller of my view, when I want to call it when clicking the button, as described in the documentation
sap.ui.define([
"sap/ui/core/mvc/Controller",
"Test_ScreenRecordingTest_ScreenRecording/lib/RecordRTC"
], function(Controller, RecordRTC) {
"use strict";
return Controller.extend("Test_ScreenRecordingTest_ScreenRecording.controller.View1", {
onStartRecording: function(){
debugger;
var mediaConstraints = { video: true, audio: true };
navigator.mediaDevices.getUserMedia(mediaConstraints).then(this.successCallback.bind(this)).catch(this.errorCallback);
},
successCallback: function(stream) {
// RecordRTC usage goes here
var options = {
mimeType: 'video/webm', // or video/webm\;codecs=h264 or video/webm\;codecs=vp9
audioBitsPerSecond: 128000,
videoBitsPerSecond: 128000,
bitsPerSecond: 128000 // if this line is provided, skip above two
};
//jQuery.sap.require("Test_ScreenRecordingTest_ScreenRecording.lib.RecordRTC");
this.recordRTC = RecordRTC(stream, options);
this.recordRTC.startRecording();
},
errorCallback: function(error) {
console.log(error)
debugger;
},
onStopRecording: function(){
this.recordRTC.stopRecording(function (audioVideoWebMURL) {
video.src = audioVideoWebMURL;
var recordedBlob = this.recordRTC.getBlob();
debugger;
this.recordRTC.getDataURL(function(dataURL) {
debugger;
});
});
}
});
If I don't use the RecordRTC variable, I can see it in the debugger. If I use it, it appears as "undefined". So can never call it.
Could you please help??Ç
EDIT 09-feb-2018: Solved declaring a new variable in the Controller extension
return Controller.extend("Test_ScreenRecordingTest_ScreenRecording.controller.View1", {
//this line solved the issue
RecordRTC: RecordRTC,
onStartRecording: function(){
debugger;
var mediaConstraints = { video: true, audio: true };
navigator.mediaDevices.getUserMedia(mediaConstraints).then(this.successCallback.bind(this)).catch(this.errorCallback);
},
Thank you in advance
The dependency string in your code looks strange:
"Test_ScreenRecordingTest_ScreenRecording/lib/RecordRTC".
Can it be a typo?
Anyway, the dependency path should be like this: "<app ID from manifest.json>/lib/RecordRTC".
Related
I am using the jsPDF library for converting a table into a PDF file.
The current code that I have used is giving off an error, that autoTable is not a function.
Here is the code.
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel",
"sap/ui/core/util/Export",
"sap/ui/core/util/ExportTypeCSV"
],
function (Controller, JSONModel, Export, ExportTypeCSV) {
"use strict";
return Controller.extend("c.g.modalproject1.controller.Root", {
onInit: function () {
var oModel1 = new JSONModel("./model/vegetableDataJSON.json");
this.getView().setModel(oModel1, "veg");
console.log("data : ", oModel1);
},
openDialog1: function () {
if (!this.pdialog1) {
this.pdialog1 = this.loadFragment({
name: "c.g.modalproject1.fragments.mTables"
});
}
this.pdialog1.then(function (oDialog) {
oDialog.open();
})
new sap.m.MessageToast.show("Table Loaded");
},
closeDialog: function () {
this.byId("newDialog1").close();
sap.m.MessageToast.show("Table closed ! ");
// var vegTable = this.getView().byId("vegiesMTable");
// vegTable.setGrowing(false);
// vegTable.setGrowingScrollToLoad(false);
},
downloadCSV: function () {
// Show a toast message to indicate that the file is downloading
sap.m.MessageToast.show("Downloading Excel..");
// Create a new Export object with the specified export type and options
var oExport = new Export({
exportType: new ExportTypeCSV({
separatorChar: ","
}),
models: this.getView().getModel("veg"),
rows: {
path: "/vegetablesRootNode"
},
columns: [{
name: "Title",
template: {
content: "{title}"
}
},
{
name: "Type",
template: {
content: "{type}"
}
},
{
name: "Description",
template: {
content: "{description}"
}
},
{
name: "Price",
template: {
content: "{price}"
}
},
{
name: "Rating",
template: {
content: "{rating}"
}
}]
});
// Save the file and handle any errors that may occur
oExport.saveFile().catch(function (oError) {
sap.m.MessageToast.show("Error when downloading data. Browser might not be supported!\n\n" + oError);
}).then(function () {
// Destroy the export object
oExport.destroy();
});
},
downloadPDF:function()
{
sap.m.MessageToast.show("Downloading into PDF started !");
var oModel2 = this.getView().getModel("veg");
console.log("check data = ", oModel2);
var oColumns = ["Title","Type","Description","Price","Rating"];
var oRows = [];
oRows = oModel2.oData.vegetablesRootNode;
console.log(oColumns);
console.log(oRows);
//var pdfDoc = new jsPDF('p', 'pt', 'letter');
var pdfDoc = new jsPDF();
pdfDoc.text(20, 20, "Vegetables Table");
pdfDoc.autoTable(oRows, oColumns);
pdfDoc.save("test.pdf");
//pdfDoc.output("save","t.pdf");
}
});
});
The last function is the code that runs to save the table data into PDF.
Can you please help.
These are the files that are included in my project folder.
Manifest.json
Adding just text, and most of the functionality that is available (via methods) from jsPDF works fine. I have created PDFs with just text from this app as well.
It works fine for adding text and downloads fine. But for Table data, it doesnt work.
I tried various ways but didn't get to solve it at all.
I tried to make a POC with this library and it works :-)
Configure the framework so that it can load the libraries
sap.ui.loader.config({
// activate real async loading and module definitions
async: true,
// load thirparty from cdn
paths: {
"thirdparty/jsPDF": "https://unpkg.com/jspdf#2.5.1/dist/jspdf.umd.min",
"thirdparty/jsPDFautoTable": "https://unpkg.com/jspdf-autotable#3.5.28/dist/jspdf.plugin.autotable"
},
// provide dependency and export metadata for non-UI5 modules
shim: {
"thirdparty/jsPDF": {
amd: true,
exports: "jspdf"
},
"thirdparty/jsPDFautoTable": {
amd: true,
exports: "jspdf",
deps: ["thirdparty/jsPDF"]
}
}
});
You can put that code on top on your Component.js file
Idea is to configure the framework to load libraries from CDN as AMD module with dependencies.
It's a bit tricky in your case and I'm not sure I understand the mechanism; what I imagine is that autoTable is a jsPDF plugin so we need jsPDF (dependency); the plugin overload jsPDF and returns jsPDF object
For sap.ui.loader here the official doc. :
https://sapui5.hana.ondemand.com/sdk/#/api/sap.ui.loader/methods/sap.ui.loader.config
Loads and consumes libraries
sap.ui.require(["thirdparty/jsPDFautoTable"], (jsPDFautoTable) => {
var doc = new jsPDFautoTable.jsPDF();
doc.autoTable({ html: '#my-table' });
doc.save('table.pdf');
});
Either with sap.ui.define or sap.ui.require to load the library on the fly when needed
I'm using videojs in a vue application to play a pre-signed URL for a mp4 video file on S3. I'm using the pre-signed URL as the source of the videojs player but I get the error
The media could not be loaded, either because the server or network
failed or because the format is not supported.
This is how my URL looks like:
https://bucket-name.s3.region.amazonaws.com/object.mp4?AWSAccessKeyId=xxxxxxxxxxxx&Expires=xxxxxxx&Signature=xxxxxx&x-amz-security-token=xxxxxxx
I looked at similar questions on SO and someone suggested to change the URL format to below format, but that didn't work either.
https://s3.amazonaws.com/bucket-name/object.mp4?AWSAccessKeyId=xxxxxxxxxxxx&Expires=xxxxxxx&Signature=xxxxxx&x-amz-security-token=xxxxxxx
The video player plays the video if I put either of the above hardcoded URLs as its source, but not when I do as variables.
Why is it changing behaviour when a variable is used ?
<template>
<div>
<video-player
:options="{
autoplay: false,
controls: true,
sources: [
{
src: `${URL}`,
type: 'video/mp4',
},
],
}"
/>
</div>
</template>
<script>
import VideoPlayer from '#/components/VideoPlayer.vue';
var AWS = require('aws-sdk');
var bucketName = 'xxxx';
var s3 = new AWS.S3({
apiVersion: '2006-03-01',
params: { Bucket: bucketName },
});
export default {
components: {
VideoPlayer,
},
data() {
return {
URL: String,
};
},
methods: {
getURL() {
var self = this;
let myPromise = new Promise(function (myResolve, myReject) {
const url = s3.getSignedUrl('getObject', {
Key: `xxxxx.mp4`,
Expires: 3600,
});
myResolve(url);
myReject('sorry, error');
});
myPromise.then(
function (value) {
self.URL = value;
},
function (error) {
console.log(error);
}
);
},
},
mounted() {
this.getURL();
},
};
</script>
The issue was that the URL value was not being set as the source, as mentioned by #misterben.
I made the following changes to set the source in the method. Although there might be better ways of setting the source in Vue ( other than using querySelector)
<video-player
:options="{
autoplay: false,
controls: true,
}"
/>
</div>
and,
import videojs from 'video.js';
getSignedUrl() {
// this is because the imported videoPlayer component has class="video-js"
var player = videojs(document.querySelector('.video-js'));
var self = this;
var params = {
Bucket: 'xxxxx',
Key: `xxxxx`,
};
var promise = s3.getSignedUrlPromise('getObject', params);
promise.then(
async function (url) {
self.URL = url;
await player.src({
src: url,
type: 'video/mp4' /*video type*/,
});
},
function (err) {
console.log(err);
}
);
},
Ho to everyone. I followed this tutorial to create a modal view with a pdf generated with pdfmake.
http://gonehybrid.com/how-to-create-and-display-a-pdf-file-in-your-ionic-app/
My simply question is how can i save the pdf in my local storage on in cache? I need that to send the pdf by email or open it with openfile2. I'm using Ionic and cordova.
I don't know how you code it, but I know what plugin you should use:
https://github.com/apache/cordova-plugin-file
The git contains a complete documentation of the plugin so everything you could need should be there.
Sample code to write pdf file in device using cordova file and file transfer plugin:
var fileTransfer = new FileTransfer();
if (sessionStorage.platform.toLowerCase() == "android") {
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, onFileSystemSuccess, onError);
} else {
// for iOS
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, onError);
}
function onError(e) {
navigator.notification.alert("Error : Downloading Failed");
};
function onFileSystemSuccess(fileSystem) {
var entry = "";
if (sessionStorage.platform.toLowerCase() == "android") {
entry = fileSystem;
} else {
entry = fileSystem.root;
}
entry.getDirectory("Cordova", {
create: true,
exclusive: false
}, onGetDirectorySuccess, onGetDirectoryFail);
};
function onGetDirectorySuccess(dir) {
cdr = dir;
dir.getFile(filename, {
create: true,
exclusive: false
}, gotFileEntry, errorHandler);
};
function gotFileEntry(fileEntry) {
// URL in which the pdf is available
var documentUrl = "http://localhost:8080/testapp/test.pdf";
var uri = encodeURI(documentUrl);
fileTransfer.download(uri, cdr.nativeURL + "test.pdf",
function(entry) {
// Logic to open file using file opener plugin
},
function(error) {
navigator.notification.alert(ajaxErrorMsg);
},
false
);
};
I am trying to set the getusermedia video constraints like setting min/max frame-rates and resolutions etc... in my peer.js webrtc application which is a simple peer to peer chat application. I have being trying to integrate it into my application but it seems to break it.Any help would be greatly appreciated other online tutorials look different to my app set up. Down at function 1 is where I have been trying to set the constraints it just doesn't show the video anymore. Is this the correct place?
Also will these constraints work on a video-file playing instead of the webcam?. I am using the Google chrome flags that plays a video file instead of a camera.
navigator.getWebcam = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
// PeerJS object ** FOR PRODUCTION, GET YOUR OWN KEY at http://peerjs.com/peerserver **
var peer = new Peer({
key: 'XXXXXXXXXXXXXXXX',
debug: 3,
config: {
'iceServers': [{
url: 'stun:stun.l.google.com:19302'
}, {
url: 'stun:stun1.l.google.com:19302'
}, {
url: 'turn:numb.viagenie.ca',
username: "XXXXXXXXXXXXXXXXXXXXXXXXX",
credential: "XXXXXXXXXXXXXXXXX"
}]
}
});
// On open, set the peer id so when peer is on we display our peer id as text
peer.on('open', function(){
$('#my-id').text(peer.id);
});
peer.on('call', function(call) {
// Answer automatically for demo
call.answer(window.localStream);
step3(call);
});
// Click handlers setup
$(function() {
$('#make-call').click(function() {
//Initiate a call!
var call = peer.call($('#callto-id').val(), window.localStream);
step3(call);
});
$('end-call').click(function() {
window.existingCall.close();
step2();
});
// Retry if getUserMedia fails
$('#step1-retry').click(function() {
$('#step1-error').hide();
step();
});
// Get things started
step1();
});
function step1() {
//Get audio/video stream
navigator.getWebcam({audio: true, video: true}, function(stream){
// Display the video stream in the video object
$('#my-video').prop('src', URL.createObjectURL(stream));
// Displays error
window.localStream = stream;
step2();
}, function(){ $('#step1-error').show(); });
}
function step2() { //Adjust the UI
$('#step1', '#step3').hide();
$('#step2').show();
}
function step3(call) {
// Hang up on an existing call if present
if (window.existingCall) {
window.existingCall.close();
}
// Wait for stream on the call, then setup peer video
call.on('stream', function(stream) {
$('#their-video').prop('src', URL.createObjectURL(stream));
});
$('#step1', '#step2').hide();
$('#step3').show();
}
Your JavaScript looks invalid. You can't declare a var inside a function argument list. Did you paste wrong? Try:
var constraints = {
audio: false,
video: { mandatory: { minWidth: 1280, minHeight: 720 } }
};
navigator.getWebcam(constraints, function(stream){ etc. }
Now it's valid JavaScript at least. I'm not familiar with PeerJS, but the constraints you're using look like the Chrome ones, so if you're on Chrome then hopefully they'll work, unless PeerJS does it differently for some reason.
Your subject says "WebRTC Camera constraints" so I should mention that the Chrome constraints are non-standard. See this answer for an explanation.
Edit 11/16/14: Version Information
DEBUG: Ember : 1.7.0 ember-1.7.0.js:14463
DEBUG: Ember Data : 1.0.0-beta.10+canary.30d6bf849b ember-1.7.0.js:14463
DEBUG: Handlebars : 1.1.2 ember-1.7.0.js:14463
DEBUG: jQuery : 1.10.2
I'm beating my head against a wall trying to do something that I think should be fairly straightforward with ember and ember-data, but I haven't had any luck so far.
Essentially, I want to use server data to populate a <select> dropdown menu. When the form is submitted, a model should be created based on the data the user chooses to select. The model is then saved with ember data and forwarded to the server with the following format:
{
"File": {
"fileName":"the_name.txt",
"filePath":"/the/path",
"typeId": 13,
"versionId": 2
}
}
The problem is, the typeId and versionId are left out when the model relationship is defined as async like so:
App.File = DS.Model.extend({
type: DS.belongsTo('type', {async: true}),
version: DS.belongsTo('version', {async: true}),
fileName: DS.attr('string'),
filePath: DS.attr('string')
});
The part that is confusing me, and probably where my mistakes lie, is the controller:
App.FilesNewController = Ember.ObjectController.extend({
needs: ['files'],
uploadError: false,
// These properties will be given by the binding in the view to the
//<select> inputs.
selectedType: null,
selectedVersion: null,
files: Ember.computed.alias('controllers.files'),
actions: {
createFile: function() {
this.createFileHelper();
}
},
createFileHelper: function() {
var selectedType = this.get('selectedType');
var selectedVersion = this.get('selectedVersion');
var file = this.store.createRecord('file', {
fileName: 'the_name.txt',
filePath: '/the/path'
});
var gotDependencies = function(values) {
//////////////////////////////////////
// This only works when async: false
file.set('type', values[0])
.set('version', values[1]);
//////////////////////////////////////
var onSuccess = function() {
this.transitionToRoute('files');
}.bind(this);
var onFail = function() {
this.set('uploadError', true);
}.bind(this);
file.save().then(onSuccess, onFail);
}.bind(this);
Ember.RSVP.all([
selectedType,
selectedVersion
]).then(gotDependencies);
}
});
When async is set to false, ember handles createRecord().save() POST requests correctly.
When async is true, ember handles GET requests perfectly with multiple requests, but does NOT add the belongsTo relationships to the file JSON during createRecord().save(). Only the basic properties are serialized:
{"File":{"fileName":"the_name.txt","filePath":"/the/path"}}
I realize this question has been asked before but I have not found a satisfactory answer thus far and I have not found anything that suits my needs. So, how do I get the belongsTo relationship to serialize properly?
Just to be sure that everything is here, I will add the custom serialization I have so far:
App.ApplicationSerializer = DS.RESTSerializer.extend({
serializeIntoHash: function(data, type, record, options) {
var root = Ember.String.capitalize(type.typeKey);
data[root] = this.serialize(record, options);
},
keyForRelationship: function(key, type){
if (type === 'belongsTo') {
key += "Id";
}
if (type === 'hasMany') {
key += "Ids";
}
return key;
}
});
App.FileSerializer = App.ApplicationSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
type: { serialize: 'id' },
version: { serialize: 'id' }
}
});
And a select:
{{ view Ember.Select
contentBinding="controller.files.versions"
optionValuePath="content"
optionLabelPath="content.versionStr"
valueBinding="controller.selectedVersion"
id="selectVersion"
classNames="form-control"
prompt="-- Select Version --"}}
If necessary I will append the other routes and controllers (FilesRoute, FilesController, VersionsRoute, TypesRoute)
EDIT 11/16/14
I have a working solution (hack?) that I found based on information in two relevant threads:
1) How should async belongsTo relationships be serialized?
2) Does async belongsTo support related model assignment?
Essentially, all I had to do was move the Ember.RSVP.all() to after a get() on the properties:
createFileHelper: function() {
var selectedType = this.get('selectedType');
var selectedVersion = this.get('selectedVersion');
var file = this.store.createRecord('file', {
fileName: 'the_name.txt',
filePath: '/the/path',
type: null,
version: null
});
file.set('type', values[0])
.set('version', values[1]);
Ember.RSVP.all([
file.get('type'),
file.get('version')
]).then(function(values) {
var onSuccess = function() {
this.transitionToRoute('files');
}.bind(this);
var onFail = function() {
alert("failure");
this.set('uploadError', true);
}.bind(this);
file.save().then(onSuccess, onFail);
}.bind(this));
}
So I needed to get() the properties that were belongsTo relationships before I save the model. I don't know is whether this is a bug or not. Maybe someone with more knowledge about emberjs can help shed some light on that.
See the question for more details, but the generic answer that I worked for me when saving a model with a belongsTo relationship (and you specifically need that relationship to be serialized) is to call .get() on the properties and then save() them in then().
It boils down to this:
var file = this.store.createRecord('file', {
fileName: 'the_name.txt',
filePath: '/the/path',
type: null,
version: null
});
// belongsTo set() here
file.set('type', selectedType)
.set('version', selectedVersion);
Ember.RSVP.all([
file.get('type'),
file.get('version')
]).then(function(values) {
var onSuccess = function() {
this.transitionToRoute('files');
}.bind(this);
var onFail = function() {
alert("failure");
this.set('uploadError', true);
}.bind(this);
// Save inside then() after I call get() on promises
file.save().then(onSuccess, onFail);
}.bind(this));