Multimedia

API Reference: Device.Multimedia

Multimedia manages camera, video and image. Quick head-start for commonly used methods can be located at the example code below:

TypeScript
JavaScript
TypeScript
import PageSampleDesign from 'generated/pages/pageSample';
import FlexLayout = require('sf-core/ui/flexlayout');
import Application = require('sf-core/application');
import ImageView = require("sf-core/ui/imageview");
import Multimedia = require("sf-core/device/multimedia");
import Button = require('sf-core/ui/button');
//You should create new Page from UI-Editor and extend with it.
export default class Sample extends PageSampleDesign {
btnTakePhoto: Button;
btnPickPhoto: Button;
myImageView: ImageView;
constructor() {
super();
// Overrides super.onShow method
this.onShow = onShow.bind(this, this.onShow.bind(this));
// Overrides super.onLoad method
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
this.layout.flexDirection = FlexLayout.FlexDirection.COLUMN;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
}
/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
* @param {function} superOnShow super onShow function
* @param {Object} parameters passed from Router.go function
*/
function onShow(superOnShow: () => void) {
const { headerBar } = this;
superOnShow();
Application.statusBar.visible = false;
headerBar.visible = false;
}
/**
* @event onLoad
* This event is called once when page is created.
* @param {function} superOnLoad super onLoad function
*/
function onLoad(superOnLoad: () => void) {
superOnLoad();
this.btnTakePhoto = new Button({
text: "Take A Photo",
onPress: () => {
Multimedia.capturePhoto({
onSuccess: ({ image }) => {
this.myImageView.image = image;
},
aspectRatio: {
x: 1,
y: 1
},
allowsEditing: true,
page: this
});
}
});
this.btnPickPhoto = new Button({
text: "Pick from Gallery",
onPress: () => {
Multimedia.pickFromGallery({
type: Multimedia.Action.IMAGE,
allowsEditing: true,
onSuccess: ({ image }) => {
this.myImageView.image = image;
},
page: this
});
}
});
this.myImageView = new ImageView();
this.layout.addChild(this.myImageView, "myImageView", ".sf-imageView", {
left: 0,
width: 200,
height: 200,
backgrounColor: "#eaedf2",
imageFillType: "ASPECTFIT"
});
this.layout.addChild(this.btnTakePhoto, "btnTakePhoto", ".sf-button", {
height: 70,
width: 150,
margin: 10
});
this.layout.addChild(this.btnPickPhoto, "btnPickPhoto", ".sf-button", {
height: 70,
width: 150
});
}
JavaScript
const Color = require("sf-core/ui/color");
const ImageView = require("sf-core/ui/imageview");
const FlexLayout = require("sf-core/ui/flexlayout");
const Multimedia = require("sf-core/device/multimedia");
const Page = require("sf-core/ui/page");
const extend = require("js-base/core/extend");
const Button = require('sf-core/ui/button');
module.exports = extend(Page)(
function(_super) {
const page = this;
_super(this, {
onLoad: () => {
let btnTakePhoto = new Button({
height: 70,
width: 150,
margin: 10,
text: "Take A Photo",
onPress: () => {
Multimedia.capturePhoto({
onSuccess: ({ image }) => {
this.myImageView.image = image;
},
aspectRatio: {
x: 1,
y: 1
},
allowsEditing: true,
page: this
});
}
});
let btnPickPhoto = new Button({
height: 70,
width: 150,
text: "Pick from Gallery",
onPress: () => {
Multimedia.pickFromGallery({
type: Multimedia.Type.IMAGE,
allowsEditing: true,
onSuccess: ({ image }) => {
myImageView.image = image;
},
page
});
}
});
var myImageView = new ImageView({
left: 0,
width: 200,
height: 200,
backgrounColor: Color.create("#eaedf2"),
imageFillType: ImageView.FillType.ASPECTFIT,
});
page.layout.addChild(myImageView);
page.layout.addChild(btnTakePhoto);
page.layout.addChild(btnPickPhoto);
}
});
page.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
page.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
);

Capture a Photo from Camera

Capturing a photo is possible by using existing camera applications. Fortunately, most mobile devices already have a camera application that records video.

This example shows capturing a photo with default configurations.

Multimedia.capturePhoto({
onSuccess: ({ image }) => {
console.info("Capture Photo Succeed");
},
page: this
});

For more parameters about capturePhoto, you can refer to the API Documentation.

Record a Video from Camera

Recording a video is possible by using existing camera applications. Fortunately, most mobile devices already have a camera application that records video.

The example below shows recording a video with passed quality and maximum video time.

For more parameters about recordVideo, you can refer to the API Documentation.

Multimedia.recordVideo({
page: this,
videoQuality: Multimedia.VideoQuality.HIGH,
maximumDuration: 10,
onSuccess: ({ video: File }) => {
console.info("Record Video Succeed");
}
})

To write/read recorded video file, developer should obtain read/write external storage permission for Android.

To tweak the video quality, refer to the documentation below:

Picking Media from Gallery

If needed, you can access to the native Gallery application to get desired image or video.

In the current state, picking multiple photos on gallery is under development.

Multimedia.pickFromGallery({
type: Multimedia.Action.IMAGE,
onSuccess: ({ image }) => {
// Do other stuff with image. Example:
this.imageView1.image = image;
},
page: this
});
import Multimedia from 'sf-core/device/multimedia';
import VideoView from 'sf-core/ui/videoview';
Multimedia.pickFromGallery({
type: Multimedia.Type.VIDEO,
onSuccess: ({ video }) => {
// Do other stuff with video. Example to show on videoView:
this.videoView1.loadFile(video);
},
page: this
});

Limiting Duration on a Video

If you wish to have a limit on your picked videos like duration, you should create a dummy videoView and get the duration there. This method should be handled in async.

import Multimedia from 'sf-core/device/multimedia';
import VideoView from 'sf-core/ui/videoview';
async function getDurationOfGalleryVideoInSeconds(): Promise<number> {
return new Promise((resolve, reject) => {
Multimedia.pickFromGallery({
type: Multimedia.Type.VIDEO,
onSuccess: ({ video }) => {
try {
const dummyVideoView = new VideoView();
dummyVideoView.onReady = () => {
// totalDuration returns the duration in miliseconds. Converting to seconds
const duration = Math.floor(dummyVideoView.totalDuration / 1000);
resolve(duration);
};
dummyVideoView.loadFile(video);
}
catch (e) {
reject(`Video couldn't be loaded`);
}
},
onCancel: () => {
// Optional event for promise
reject(`user didn't select a video`);
},
onFailure: () => {
// Optional event for promise
reject(`video couldn't be selected`);
},
page: this
});
});
}

allowsEditing property shows a screen to the user that can crop the image. For more parameters, you can refer to the API Documentation

Untitled
Multimedia.pickFromGallery({
allowsEditing : true,
type: Multimedia.Action.IMAGE,
onSuccess: function ({ image }) {
// Do s
},
page : this
});

Crop Window Aspect Ratio

You can set the aspect ratio of the cropping window for android. Default behavior is free aspect ratio mode.

Untitled
Multimedia.pickFromGallery({
allowsEditing : true,
aspectRatio : {
x: 1,
y: 1
},
type: Multimedia.Type.IMAGE,
onSuccess: function (picked) {
var image = picked.image;
},
page : this
});

Cropping on Android

In Android, cropping is an activity itself. So it is necessary to define cropping activity to your AndroidManifest.xml before publishing. Activities are always defined under the tag.

<activity android:name="io.smartface.android.sfcore.device.multimedia.crop.SFCropActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>

Android Circular Crop

The Circular shape is available for both camera and gallery image.

Note:

Cropped images with circular shapes will not produce a circular radius image. the rounded radius should be added to the image.

TypeScript
JavaScript
TypeScript
import PageSampleDesign from 'generated/pages/pageSample';
import FlexLayout from 'sf-core/ui/flexlayout';
import Application from 'sf-core/application';
import ImageView from 'sf-core/ui/imageview';
import Multimedia from 'sf-core/device/multimedia';
import Button from 'sf-core/ui/button';
//You should create new Page from UI-Editor and extend with it.
export default class Sample extends PageSampleDesign {
btnTakePhoto: Button;
btnPickPhoto: Button;
myImageView: ImageView;
constructor() {
super();
// Overrides super.onShow method
this.onShow = onShow.bind(this, this.onShow.bind(this));
// Overrides super.onLoad method
this.onLoad = onLoad.bind(this, this.onLoad.bind(this));
this.layout.flexDirection = FlexLayout.FlexDirection.COLUMN;
this.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
this.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
}
/**
* @event onShow
* This event is called when a page appears on the screen (everytime).
* @param {function} superOnShow super onShow function
* @param {Object} parameters passed from Router.go function
*/
function onShow(superOnShow: () => void) {
const { headerBar } = this;
superOnShow();
Application.statusBar.visible = false;
headerBar.visible = false;
}
/**
* @event onLoad
* This event is called once when page is created.
* @param {function} superOnLoad super onLoad function
*/
function onLoad(superOnLoad: () => void) {
superOnLoad();
this.btnTakePhoto = new Button({
text: "Take A Photo",
onPress: () => {
Multimedia.capturePhoto({
onSuccess: ({ image }) => {
this.myImageView.image = image.android.round(100);
},
aspectRatio: {
x: 1,
y: 1
},
allowsEditing: true,
page: this,
android: {
cropShape: Multimedia.Android.CropShape.OVAL
}
});
}
});
this.btnPickPhoto = new Button({
text: "Pick from Gallery",
onPress: () => {
Multimedia.pickFromGallery({
type: Multimedia.Type.IMAGE,
allowsEditing: true,
onSuccess: ({ image }) => {
this.myImageView.image = image.android.round(100);
},
android: {
cropShape: Multimedia.Android.CropShape.OVAL
},
page: this
});
}
});
this.myImageView = new ImageView();
this.layout.addChild(this.myImageView, "myImageView", ".sf-imageView", {
left: 0,
width: 200,
height: 200,
backgrounColor: "#eaedf2",
imageFillType: "ASPECTFIT"
});
this.layout.addChild(this.btnTakePhoto, "btnTakePhoto", ".sf-button", {
height: 70,
width: 150,
margin: 10
});
this.layout.addChild(this.btnPickPhoto, "btnPickPhoto", ".sf-button", {
height: 70,
width: 150
});
}
JavaScript
const Color = require("sf-core/ui/color");
const ImageView = require("sf-core/ui/imageview");
const FlexLayout = require("sf-core/ui/flexlayout");
const Multimedia = require("sf-core/device/multimedia");
const Page = require("sf-core/ui/page");
const extend = require("js-base/core/extend");
const Button = require('sf-core/ui/button');
module.exports = extend(Page)(
function(_super) {
const page = this;
_super(this, {
onLoad: () => {
let btnTakePhoto = new Button({
height: 70,
width: 150,
margin: 10,
text: "Take A Photo",
onPress: () => {
Multimedia.startCamera({
onSuccess: ({ image }) => {
myImageView.image = image;
myImageView.image = myImageView.image.android.round(100);
},
aspectRatio: {
x: 1,
y: 1
},
allowsEditing: true,
action: Multimedia.ActionType.IMAGE_CAPTURE,
android: {
cropShape: Multimedia.Android.CropShape.OVAL
},
page
});
}
});
let btnPickPhoto = new Button({
height: 70,
width: 150,
text: "Pick from Gallery",
onPress: () => {
Multimedia.pickFromGallery({
type: Multimedia.Type.IMAGE,
allowsEditing: true,
onSuccess: ({ image }) => {
myImageView.image = image;
myImageView.image = myImageView.image.android.round(100);
},
android: {
cropShape: Multimedia.Android.CropShape.OVAL
},
page
});
}
});
var myImageView = new ImageView({
left: 0,
width: 200,
height: 200,
backgrounColor: Color.create("#eaedf2"),
imageFillType: ImageView.FillType.ASPECTFIT,
});
page.layout.addChild(myImageView);
page.layout.addChild(btnTakePhoto);
page.layout.addChild(btnPickPhoto);
}
});
page.layout.justifyContent = FlexLayout.JustifyContent.CENTER;
page.layout.alignItems = FlexLayout.AlignItems.CENTER;
}
);