在 ionic3 中从本地存储创建视频列表的缩略图
Creating thumbnail of list of videos from local storage in ionic3
我正在尝试从文件中读取视频列表,并以带有视频缩略图的列表形式在离子组件中显示它们file.But没有为每个文件正确创建缩略图。
videos.ts
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, LoadingController, ToastController, PopoverController, AlertController } from 'ionic-angular';
import { DataService } from '../../services/data-service';
import { File } from '@ionic-native/file';
import { VideoPlayer } from '@ionic-native/video-player';
import { VideoEditor } from '@ionic-native/video-editor';
import { SocialSharing } from '@ionic-native/social-sharing';
import { StreamingMedia, StreamingVideoOptions } from '@ionic-native/streaming-media';
@IonicPage()
@Component({
selector: 'page-recent-video',
templateUrl: 'recent-video.html',
})
export class VideosPage {
public videos:any[]=[];
public flag:boolean = false;
public thumb:string;
public videoWithThumb:any[]=[]
constructor(public navCtrl: NavController,
public navParams: NavParams,
public file:File,
public loadingCtrl:LoadingController,
public dataService:DataService,
public videoPlayer:VideoPlayer,
public videoEditor:VideoEditor,
public toastCtrl:ToastController,
public socialShare:SocialSharing,
public popoverCtrl:PopoverController,
public alertCtrl:AlertController,
public mediaPlayer:StreamingMedia ) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad RecentVideoPage');
this.loadVideos()
}
loadVideos(){
if(this.flag == true){
this.videos.splice(0, this.videos.length)
this.videoWithThumb.splice(0, this.videoWithThumb.length)
}else{
this.flag = true
}
const loading = this.loadingCtrl.create({
content:'loading videos..',
duration:2000
})
loading.present()
this.file.listDir(this.file.externalRootDirectory,'FolderName')
.then( dir =>{
for(let dirData of dir)
{
if(dirData.isFile == true && this.fileType(dirData) =='mp4'){
this.storeVideo(dirData.nativeURL, dirData.name )
}
}
loading.dismiss()
})
.catch( err=>{
console.log('reading directory error '+ err)
this.showAlert(err)
})
}
playVideo(item){
let options: StreamingVideoOptions = {
successCallback: () => { console.log('Video played') },
errorCallback: (e) => { console.log('Error streaming') },
orientation: 'portrait'
};
this.mediaPlayer.playVideo(item.url, options);
}
showAlert(msg:string){
const alert = this.alertCtrl.create({
title:'Failed',
subTitle:msg,
buttons:['OK']
})
alert.present()
}
fileType(dirData){
const indexOfLastDot = dirData.nativeURL.lastIndexOf('.');
// const path = dirData.nativeURL.substring(0, indexOfLastDot);
const fileType = dirData.nativeURL.substring(indexOfLastDot + 1);
console.log(fileType)
return fileType
}
storeVideo( url, name ){
this.videos.push({ url:url , name:name })
}
showToast(msg:string){
const toast = this.toastCtrl.create({
message:msg,
duration:2000,
position:'middle'
})
toast.present()
}
}
videos.html
<ion-content padding class="card-background-page">
<!-- webkit-playsinline="webkit-playsinline" -->
<ion-card no-margin margin-bottom class="full-width" overflow-scroll="true"
*ngFor="let item of videos">
<video width="320" height="240" controls="controls"
preload="metadata"
poster= '{{item | createThumbnail}}'
webkit-playsinline="webkit-playsinline"
class="videoPlayer">
<source [src]="item.url" type="video/mp4"/></video>
</ion-card>
<ion-fab right bottom>
<button ion-fab mini color="topBar" tappable (tap)="loadVideos()"><ion-icon name="refresh"></ion-icon></button>
</ion-fab>
</ion-content>
videos.module.ts
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { VideosPage } from './recent-video';
import { PipesModule } from '../../pipes/pipes.module';
@NgModule({
declarations: [
VideosPage,
],
imports: [
IonicPageModule.forChild(VideosPage),
PipesModule
],
})
export class VideosPageModule {}
**pipe used for creating thumbnail of each item in the list**
创建-thumbnail.ts
import { Pipe, PipeTransform } from '@angular/core';
import { VideoEditor } from '@ionic-native/video-editor';
@Pipe({
name: 'createThumbnail',
})
export class CreateThumbnailPipe implements PipeTransform {
public thumb: string;
constructor(public videoEditor:VideoEditor){
}
transform(value: any) {
this.videoEditor.createThumbnail({fileUri:value.url, outputFileName:value.name, atTime:2, width:320, height:240,quality:100} )
.then(ref=>{
console.log(ref)
this.thumb = ref;
// console.log('generated thumb '+ this.thumb )
})
.catch(err=>{
console.log(err)
})
console.log('returning thumb '+ this.thumb)
return this.thumb
}
}
pipe.module.ts
import { NgModule } from '@angular/core';
import { CreateThumbnailPipe } from './create-thumbnail/create-thumbnail';
@NgModule({
declarations: [CreateThumbnailPipe],
imports: [],
exports: [CreateThumbnailPipe]
})
export class PipesModule {}
仅为第一个文件创建了缩略图。对于其余的视频文件,请使用之前创建的相同缩略图,请帮助我解决此问题。
" Thumbnail for only fist file is created " because you used
Reason-
createThumbnail() -
it take some time to create thumbnail of video but in other side html done its work fast so html pass first url to this function and then this function is busy to make thumbnail of it,but html send all the url to this function but it is still busy so its only create one thumbnail.
Solution -
you must have to make **async** and **await** task or function so that html wait for createThumbnail().so every time html send url to this function then html wait for that function task and then send next url to that function.
here's my code for create thumbnails
async favourite(fileName){
let thumbName = fileName.substr(fileName.lastIndexOf('/') + 1);
const result = await this.commonserviceProvider.thumbUpload(thumbName,fileName); //this service is called for create thumbanils and favourite() function wait for this service
let videoName = fileName.match(/([^\/]+)(?=\.\w+$)/)[0];
const result1 = await this.commonserviceProvider.upload(videoName+".mp4",this.folderPath+videoName+".mp4",1);
this.presentToast('Saved in favourite');
}
我正在尝试从文件中读取视频列表,并以带有视频缩略图的列表形式在离子组件中显示它们file.But没有为每个文件正确创建缩略图。
videos.ts
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, LoadingController, ToastController, PopoverController, AlertController } from 'ionic-angular';
import { DataService } from '../../services/data-service';
import { File } from '@ionic-native/file';
import { VideoPlayer } from '@ionic-native/video-player';
import { VideoEditor } from '@ionic-native/video-editor';
import { SocialSharing } from '@ionic-native/social-sharing';
import { StreamingMedia, StreamingVideoOptions } from '@ionic-native/streaming-media';
@IonicPage()
@Component({
selector: 'page-recent-video',
templateUrl: 'recent-video.html',
})
export class VideosPage {
public videos:any[]=[];
public flag:boolean = false;
public thumb:string;
public videoWithThumb:any[]=[]
constructor(public navCtrl: NavController,
public navParams: NavParams,
public file:File,
public loadingCtrl:LoadingController,
public dataService:DataService,
public videoPlayer:VideoPlayer,
public videoEditor:VideoEditor,
public toastCtrl:ToastController,
public socialShare:SocialSharing,
public popoverCtrl:PopoverController,
public alertCtrl:AlertController,
public mediaPlayer:StreamingMedia ) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad RecentVideoPage');
this.loadVideos()
}
loadVideos(){
if(this.flag == true){
this.videos.splice(0, this.videos.length)
this.videoWithThumb.splice(0, this.videoWithThumb.length)
}else{
this.flag = true
}
const loading = this.loadingCtrl.create({
content:'loading videos..',
duration:2000
})
loading.present()
this.file.listDir(this.file.externalRootDirectory,'FolderName')
.then( dir =>{
for(let dirData of dir)
{
if(dirData.isFile == true && this.fileType(dirData) =='mp4'){
this.storeVideo(dirData.nativeURL, dirData.name )
}
}
loading.dismiss()
})
.catch( err=>{
console.log('reading directory error '+ err)
this.showAlert(err)
})
}
playVideo(item){
let options: StreamingVideoOptions = {
successCallback: () => { console.log('Video played') },
errorCallback: (e) => { console.log('Error streaming') },
orientation: 'portrait'
};
this.mediaPlayer.playVideo(item.url, options);
}
showAlert(msg:string){
const alert = this.alertCtrl.create({
title:'Failed',
subTitle:msg,
buttons:['OK']
})
alert.present()
}
fileType(dirData){
const indexOfLastDot = dirData.nativeURL.lastIndexOf('.');
// const path = dirData.nativeURL.substring(0, indexOfLastDot);
const fileType = dirData.nativeURL.substring(indexOfLastDot + 1);
console.log(fileType)
return fileType
}
storeVideo( url, name ){
this.videos.push({ url:url , name:name })
}
showToast(msg:string){
const toast = this.toastCtrl.create({
message:msg,
duration:2000,
position:'middle'
})
toast.present()
}
}
videos.html
<ion-content padding class="card-background-page">
<!-- webkit-playsinline="webkit-playsinline" -->
<ion-card no-margin margin-bottom class="full-width" overflow-scroll="true"
*ngFor="let item of videos">
<video width="320" height="240" controls="controls"
preload="metadata"
poster= '{{item | createThumbnail}}'
webkit-playsinline="webkit-playsinline"
class="videoPlayer">
<source [src]="item.url" type="video/mp4"/></video>
</ion-card>
<ion-fab right bottom>
<button ion-fab mini color="topBar" tappable (tap)="loadVideos()"><ion-icon name="refresh"></ion-icon></button>
</ion-fab>
</ion-content>
videos.module.ts
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { VideosPage } from './recent-video';
import { PipesModule } from '../../pipes/pipes.module';
@NgModule({
declarations: [
VideosPage,
],
imports: [
IonicPageModule.forChild(VideosPage),
PipesModule
],
})
export class VideosPageModule {}
**pipe used for creating thumbnail of each item in the list**
创建-thumbnail.ts
import { Pipe, PipeTransform } from '@angular/core';
import { VideoEditor } from '@ionic-native/video-editor';
@Pipe({
name: 'createThumbnail',
})
export class CreateThumbnailPipe implements PipeTransform {
public thumb: string;
constructor(public videoEditor:VideoEditor){
}
transform(value: any) {
this.videoEditor.createThumbnail({fileUri:value.url, outputFileName:value.name, atTime:2, width:320, height:240,quality:100} )
.then(ref=>{
console.log(ref)
this.thumb = ref;
// console.log('generated thumb '+ this.thumb )
})
.catch(err=>{
console.log(err)
})
console.log('returning thumb '+ this.thumb)
return this.thumb
}
}
pipe.module.ts
import { NgModule } from '@angular/core';
import { CreateThumbnailPipe } from './create-thumbnail/create-thumbnail';
@NgModule({
declarations: [CreateThumbnailPipe],
imports: [],
exports: [CreateThumbnailPipe]
})
export class PipesModule {}
仅为第一个文件创建了缩略图。对于其余的视频文件,请使用之前创建的相同缩略图,请帮助我解决此问题。
" Thumbnail for only fist file is created " because you used
Reason-
createThumbnail() -
it take some time to create thumbnail of video but in other side html done its work fast so html pass first url to this function and then this function is busy to make thumbnail of it,but html send all the url to this function but it is still busy so its only create one thumbnail.
Solution -
you must have to make **async** and **await** task or function so that html wait for createThumbnail().so every time html send url to this function then html wait for that function task and then send next url to that function.
here's my code for create thumbnails
async favourite(fileName){
let thumbName = fileName.substr(fileName.lastIndexOf('/') + 1);
const result = await this.commonserviceProvider.thumbUpload(thumbName,fileName); //this service is called for create thumbanils and favourite() function wait for this service
let videoName = fileName.match(/([^\/]+)(?=\.\w+$)/)[0];
const result1 = await this.commonserviceProvider.upload(videoName+".mp4",this.folderPath+videoName+".mp4",1);
this.presentToast('Saved in favourite');
}