HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

ios离线打包 集成 视频压缩功能

要想实现更多功能 适应更多应用场景 肯定是要选择离线打包的

第一步
1.在HBuilder-Hello目录下新建compressVideo文件夹,在改文件夹下新建文件SendVideoView.h和SendVideoView.m

2.SendVideoView.h代码

#include "PGPlugin.h"  
#include "PGMethod.h"  

@interface SendVideoView : PGPlugin  
    - (void)compression:(PGMethod*)commands;  
    - (CGFloat)fileSize:(NSURL*)path;  
    -(NSString *)getNowTimeTimestamp;  
@end  

3.SendVideoView.m代码

#import "SendVideoView.h"  
#import <AssetsLibrary/AssetsLibrary.h>  
#import <AVFoundation/AVFoundation.h>  

@implementation SendVideoView  
-(NSString *)getNowTimeTimestamp{  

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;  

    [formatter setDateStyle:NSDateFormatterMediumStyle];  

    [formatter setTimeStyle:NSDateFormatterShortStyle];  

    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // ------ ----设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制  

    //设置时区,这个对于时间的处理有时很重要  

    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];  

    [formatter setTimeZone:timeZone];  

    NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式  

    NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];  

    return timeSp;  

}  
//计算压缩大小  
- (CGFloat)fileSize:(NSURL*)path  
{  
    return [[NSData dataWithContentsOfURL:path] length]/1024.00 /1024.00;  
}  
//压缩  
- (void)compression:(PGMethod*)commands  
{  
    NSString* parameter0 = [commands.arguments objectAtIndex:0];  
    NSLog(@"parameter=%@",parameter0);  
    NSString* callFunc = [commands.arguments objectAtIndex:1];  
    NSURL * url = [NSURL URLWithString:parameter0];  
     NSLog(@"第一个参数=%@",parameter0);  
      NSLog(@"压缩前大小 %f MB",[self fileSize:url]);  
    //    创建AVAsset对象  
    AVAsset* asset = [AVAsset assetWithURL:url];  
    /*   创建AVAssetExportSession对象  
     压缩的质量  
     AVAssetExportPresetLowQuality   最low的画质最好不要选择实在是看不清楚  
     AVAssetExportPresetMediumQuality  使用到压缩的话都说用这个  
     AVAssetExportPresetHighestQuality  最清晰的画质  

     */  
    AVAssetExportSession * session = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];  
    //优化网络  
    session.shouldOptimizeForNetworkUse = YES;  
    //转换后的格式  

    //拼接输出文件路径 为了防止同名 可以根据日期拼接名字 或者对名字进行MD5加密  

    NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent:[[self getNowTimeTimestamp] stringByAppendingString: @".mp4"]];  
    //判断文件是否存在,如果已经存在删除  
    [[NSFileManager defaultManager]removeItemAtPath:path error:nil];  
    //设置输出路径  
    session.outputURL = [NSURL fileURLWithPath:path];  

    //设置输出类型  这里可以更改输出的类型 具体可以看文档描述  
    session.outputFileType = AVFileTypeMPEG4;  

    [session exportAsynchronouslyWithCompletionHandler:^{  
        NSLog(@"%@",[NSThread currentThread]);  

        //压缩完成  

        if (session.status==AVAssetExportSessionStatusCompleted) {  
            //在主线程中刷新UI界面,弹出控制器通知用户压缩完成  
            dispatch_async(dispatch_get_main_queue(), ^{  
                NSString* pResultString = [@"file://" stringByAppendingPathComponent:path];  
                NSLog(@"path=%@",path);  
                PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsString:pResultString];  
                [self toCallback:callFunc withReslut:[result toJSONString]];  
                NSFileManager* fileManager=[NSFileManager defaultManager];  
                // 删除沙盒中的视频  
                BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:[parameter0 substringFromIndex:7]];  
                if(blHave){  
                    BOOL blDele= [fileManager removeItemAtPath:[parameter0 substringFromIndex:7] error:nil];  
                }  
                // 以下调试时开起  
//                NSLog(@"导出完成");  
//                NSLog(@"压缩完毕,压缩后大小 %f MB",[self fileSize:session.outputURL]);  
            });  

        }  

    }];     

}  

@end

第二步
1.打开PandoraApi.bundle下的feature.plist文件

  1. feature.plist文件里加入
    <key>compressVideo</key>
    <dict>
    <key>class</key>
    <string>SendVideoView</string>
    <key>global</key>
    <true/>
    <key>autostart</key>
    <string>YES</string>
    </dict>

第三步
在html 页面 用JS通过 Native.js,调用原生类
var _BARCODE = 'compressVideo'
var B = window.plus.bridge
var compressVideo = {

compression: function (path, successCallback) {  
  var success = typeof successCallback !== 'function' ? null : function (args) {  
      successCallback(args)  
    },  
    callbackID = B.callbackId(success, null)  
  return B.exec(_BARCODE, 'compression', [path, callbackID])  
}  

}

window.plus.compressVideo = compressVideo

就这么多了,不懂的可以加群864017187(dcloud混合开发交流群)
安卓版的视频压缩,改天有空了再写出来

继续阅读 »

要想实现更多功能 适应更多应用场景 肯定是要选择离线打包的

第一步
1.在HBuilder-Hello目录下新建compressVideo文件夹,在改文件夹下新建文件SendVideoView.h和SendVideoView.m

2.SendVideoView.h代码

#include "PGPlugin.h"  
#include "PGMethod.h"  

@interface SendVideoView : PGPlugin  
    - (void)compression:(PGMethod*)commands;  
    - (CGFloat)fileSize:(NSURL*)path;  
    -(NSString *)getNowTimeTimestamp;  
@end  

3.SendVideoView.m代码

#import "SendVideoView.h"  
#import <AssetsLibrary/AssetsLibrary.h>  
#import <AVFoundation/AVFoundation.h>  

@implementation SendVideoView  
-(NSString *)getNowTimeTimestamp{  

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;  

    [formatter setDateStyle:NSDateFormatterMediumStyle];  

    [formatter setTimeStyle:NSDateFormatterShortStyle];  

    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // ------ ----设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制  

    //设置时区,这个对于时间的处理有时很重要  

    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];  

    [formatter setTimeZone:timeZone];  

    NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式  

    NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];  

    return timeSp;  

}  
//计算压缩大小  
- (CGFloat)fileSize:(NSURL*)path  
{  
    return [[NSData dataWithContentsOfURL:path] length]/1024.00 /1024.00;  
}  
//压缩  
- (void)compression:(PGMethod*)commands  
{  
    NSString* parameter0 = [commands.arguments objectAtIndex:0];  
    NSLog(@"parameter=%@",parameter0);  
    NSString* callFunc = [commands.arguments objectAtIndex:1];  
    NSURL * url = [NSURL URLWithString:parameter0];  
     NSLog(@"第一个参数=%@",parameter0);  
      NSLog(@"压缩前大小 %f MB",[self fileSize:url]);  
    //    创建AVAsset对象  
    AVAsset* asset = [AVAsset assetWithURL:url];  
    /*   创建AVAssetExportSession对象  
     压缩的质量  
     AVAssetExportPresetLowQuality   最low的画质最好不要选择实在是看不清楚  
     AVAssetExportPresetMediumQuality  使用到压缩的话都说用这个  
     AVAssetExportPresetHighestQuality  最清晰的画质  

     */  
    AVAssetExportSession * session = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];  
    //优化网络  
    session.shouldOptimizeForNetworkUse = YES;  
    //转换后的格式  

    //拼接输出文件路径 为了防止同名 可以根据日期拼接名字 或者对名字进行MD5加密  

    NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent:[[self getNowTimeTimestamp] stringByAppendingString: @".mp4"]];  
    //判断文件是否存在,如果已经存在删除  
    [[NSFileManager defaultManager]removeItemAtPath:path error:nil];  
    //设置输出路径  
    session.outputURL = [NSURL fileURLWithPath:path];  

    //设置输出类型  这里可以更改输出的类型 具体可以看文档描述  
    session.outputFileType = AVFileTypeMPEG4;  

    [session exportAsynchronouslyWithCompletionHandler:^{  
        NSLog(@"%@",[NSThread currentThread]);  

        //压缩完成  

        if (session.status==AVAssetExportSessionStatusCompleted) {  
            //在主线程中刷新UI界面,弹出控制器通知用户压缩完成  
            dispatch_async(dispatch_get_main_queue(), ^{  
                NSString* pResultString = [@"file://" stringByAppendingPathComponent:path];  
                NSLog(@"path=%@",path);  
                PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsString:pResultString];  
                [self toCallback:callFunc withReslut:[result toJSONString]];  
                NSFileManager* fileManager=[NSFileManager defaultManager];  
                // 删除沙盒中的视频  
                BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:[parameter0 substringFromIndex:7]];  
                if(blHave){  
                    BOOL blDele= [fileManager removeItemAtPath:[parameter0 substringFromIndex:7] error:nil];  
                }  
                // 以下调试时开起  
//                NSLog(@"导出完成");  
//                NSLog(@"压缩完毕,压缩后大小 %f MB",[self fileSize:session.outputURL]);  
            });  

        }  

    }];     

}  

@end

第二步
1.打开PandoraApi.bundle下的feature.plist文件

  1. feature.plist文件里加入
    <key>compressVideo</key>
    <dict>
    <key>class</key>
    <string>SendVideoView</string>
    <key>global</key>
    <true/>
    <key>autostart</key>
    <string>YES</string>
    </dict>

第三步
在html 页面 用JS通过 Native.js,调用原生类
var _BARCODE = 'compressVideo'
var B = window.plus.bridge
var compressVideo = {

compression: function (path, successCallback) {  
  var success = typeof successCallback !== 'function' ? null : function (args) {  
      successCallback(args)  
    },  
    callbackID = B.callbackId(success, null)  
  return B.exec(_BARCODE, 'compression', [path, callbackID])  
}  

}

window.plus.compressVideo = compressVideo

就这么多了,不懂的可以加群864017187(dcloud混合开发交流群)
安卓版的视频压缩,改天有空了再写出来

收起阅读 »

IOS离线打包集成 阿里云 短视频sdk

要想实现更多功能 适应更多应用场景 肯定是要选择离线打包的

1.基础版: 只有录制和裁剪功能,

  1. 标准版:可以修改UI
  2. 专业版: 很复杂的功能

可以参考,阿里云SDK说明

阿里云短视频基础版

如何没有离线打包过的,可以参考,官方最新的AS 打包教程:
ios离线打包教程

第一步
先下载ios短视频基础版SDK,详见sdk下载页面
1.开发者打开工程,选中目标target,依次选择”General”->”Embededed Binaries”,点击”+”号,点击“Add Other…”,导入QUCore-ThirdParty.framework和AliyunVideoSDK.framework。
2.同时,还需依赖libz.tbd、libc++.tbd、libiconv.tbd、libresolv.tbd、ImageIO.framework、CoreMedia.framework、CoreVideo.framework、SystemConfiguration.framework、Photos.framework、OpenAL.framework、VideoToolbox.framework请一并加上。截图如下

3.配置 Build Setting -- Build Options -- Enable Bitcode 选项为NO

4.配置 Build Setting -- Linking -- Other Linker Flags 添加 -ObjC选项

第二步
1.在HBuilder-Hello下新建文件夹recoredVideo 并在该文件夹下新建RecordVideo.h和RecordVideo.m文件

2.RecordVideo.h代码

include "PGPlugin.h"

include "PGMethod.h"

import <AliyunVideoSDK/AliyunVideoBase.h>

@interface RecordVideo : PGPlugin

  • (void)record:(PGMethod*)commands;
  • (void)videoBase:(AliyunVideoBase )base recordCompeleteWithRecordViewController:(UIViewController )recordVC videoPath:(NSString )videoPath;
    -(NSString
    )getNowTimeTimestamp;
    @end

3.RecordVideo.m代码

import "RecordVideo.h"

import <AliyunVideoSDK/AliyunVideoSDK.h>

import <AliyunVideoSDK/AliyunVideoRecordParam.h>

import <AliyunVideoSDK/AliyunVideoUIConfig.h>

import <AliyunVideoSDK/AliyunVideoBase.h>

import <AliyunVideoSDK/AliyunVideoCropParam.h>

import <AssetsLibrary/AssetsLibrary.h>

@interface RecordVideo()
@property (nonatomic,strong) NSString *callFunc;
@end

@implementation RecordVideo

  • (void)record:(PGMethod)commands
    {
    AliyunVideoUIConfig
    config = [[AliyunVideoUIConfig alloc] init];
    config.hiddenFlashButton = NO;
    config.imageBundleName = @"QPSDK";
    config.hiddenImportButton = YES;
    [[AliyunVideoBase shared] registerWithAliyunIConfig:config];

    NSString parameter0 = [commands.arguments objectAtIndex:0];
    self.callFunc = [commands.arguments objectAtIndex:1];
    NSData
    data= [parameter0 dataUsingEncoding:NSUTF8StringEncoding];
    NSError error = nil;
    id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
    NSDictionary
    dict = (NSDictionary )jsonObject;
    AliyunVideoRecordParam
    quVideo = [[AliyunVideoRecordParam alloc] init];
    quVideo.maxDuration = [[dict objectForKey:@"setMaxDuration"] doubleValue];
    quVideo.minDuration = [[dict objectForKey:@"setMinDuration"] doubleValue];
    quVideo.videoQuality = AliyunVideoQualityHight;
    quVideo.torchMode = AliyunCameraTorchModeOff;
    quVideo.size = AliyunVideoVideoSize540P;
    quVideo.gop = [[dict objectForKey:@"setGop"] intValue];
    quVideo.beautifyStatus = [[dict objectForKey:@"setBeautyStatus"] boolValue];
    quVideo.beautifyValue = [[dict objectForKey:@"setBeautyLevel"] intValue];
    quVideo.position = AliyunCameraPositionBack;
    NSString path = [NSTemporaryDirectory() stringByAppendingPathComponent:[[self getNowTimeTimestamp] stringByAppendingString: @".mp4"]];
    quVideo.outputPath = path;
    UIViewController
    recordViewController = [[AliyunVideoBase shared] createRecordViewControllerWithRecordParam:quVideo];
    [AliyunVideoBase shared].delegate = (id)self;
    [self.rootViewController.navigationController pushViewController:recordViewController animated:YES];
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    }

  • (void)videoBase:(AliyunVideoBase )base recordCompeleteWithRecordViewController:(UIViewController )recordVC videoPath:(NSString )videoPath {
    NSLog(@"录制完成 %@", videoPath);
    ALAssetsLibrary
    library = [[ALAssetsLibrary alloc] init];
    [library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:videoPath]
    completionBlock:^(NSURL assetURL, NSError error) {
    NSString path = [@"file://" stringByAppendingPathComponent:videoPath];
    NSDictionary
    dict = [NSDictionary dictionaryWithObjectsAndKeys:@"000000",@"code",path,@"path",nil];
    PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary:dict];
    [self toCallback:self.callFunc withReslut:[result toJSONString]];
    dispatch_async(dispatch_get_main_queue(), ^{
    [recordVC.navigationController popViewControllerAnimated:YES];
    });
    }];
    }

-(void)videoBaseRecordVideoExit {
NSLog(@"退出录制");
[self.rootViewController.navigationController popViewControllerAnimated:YES];
}

-(NSString *)getNowTimeTimestamp{

NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;  

[formatter setDateStyle:NSDateFormatterMediumStyle];  

[formatter setTimeStyle:NSDateFormatterShortStyle];  

[formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // ------ ----设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制  

//设置时区,这个对于时间的处理有时很重要  

NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];  

[formatter setTimeZone:timeZone];  

NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式  

NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];  

return timeSp;  

}
@end

第三步
1.打开PandoraApi.bundle下的feature.plist文件

2.feature.plist文件里加入
<key>RecordVideo</key>
<dict>
<key>class</key>
<string>RecordVideo</string>
<key>global</key>
<true/>
<key>autostart</key>
<string>YES</string>
</dict>

然后在html 页面 用JS通过 Native.js,调用原生类
var RecordVideoIos = function (options) {
this.options = this.extend(
{
setResolutionMode: '540p', // 录制 设置录制分辨率,目前支持360p,480p,540p,720p
setRatioMode: '1/1', // 录制 设置视频比例,目前支持1/1 ,3/4, 9/16
setRecordMode: 'AUTO', // 录制 设置录制模式,目前支持按录:PRESS,点录:TOUCH和混合模式:AUTO
setBeautyLevel: 80, // 录制 设置美颜度,1-100,比率
setBeautyStatus: true, // 录制 设置美颜开关
setCameraType: 'BACK', // 录制 设置前后置摄像头, 后:BACK ,前:FRONT
setFlashType: 'NO', // 录制 设置闪光灯模式,开:NO, 关:OFF, 自动:AUTO
setNeedClip: true, // 录制 设置是否需要支持片段录制
setMaxDuration: 15, // 录制 设置最大录制时长 单位秒
setMinDuration: 2, // 录制 设置最小录制时长 单位秒
setVideoQuality: 'HD', // 录制设置视频质量 4个级别, 低:LD ,中:SD ,高:HD ,极高:SSD
setGop: 125, // 设置关键帧间隔,建议:1-300之间
setMinVideoDuration: 5, // 裁剪 设置过滤的视频最小长度 单位秒
setMaxVideoDuration: 15, // 裁剪 设置过滤的视频最大长度 单位秒
setMinCropDuration: 2, // 裁剪 设置视频最小裁剪时间 单位毫秒
setFrameRate: 25, // 裁剪 设置帧率
setNeedRecord: false, // 设置是否需要开放录制入口,即选择视频的页面,多出一个录制按钮
setResulutionMode: '540p', // 设置裁剪分辨率,目前支持360p,480p,540p,720p
setCropMode: 'cpu' // 设置裁剪方式,是否使用gpu进行裁剪,不设置则默认使用cpu来裁剪
}, options)
this.init()
}

RecordVideoIos.prototype = {
init: function () {
this.event()
},
event: function () {
},
extend: function (obj, obj2) {
for (var k in obj2) {
obj[k] = obj2[k]
}
return obj
},
open: function (fn) {
let B = window.plus.bridge
let success = typeof fn !== 'function' ? null : function (args) {
fn(args)
}
let callbackID = B.callbackId(success, null)
return B.exec('RecordVideo', 'record', [JSON.stringify(this.options), callbackID])
}
}

const option = {
setResolutionMode: '720p', // 录制 设置录制分辨率,目前支持360p,480p,540p,720p
setRatioMode: '1/1', // 录制 设置视频比例,目前支持1/1 ,3/4, 9/16
setRecordMode: 'AUTO', // 录制 设置录制模式,目前支持按录:PRESS,点录:TOUCH和混合模式:AUTO
setBeautyLevel: 60, // 录制 设置美颜度,1-100,比率
setBeautyStatus: true, // 录制 设置美颜开关
setCameraType: 'BACK', // 录制 设置前后置摄像头, 后:BACK ,前:FRONT
setFlashType: 'OFF', // 录制 设置闪光灯模式,开:NO, 关:OFF, 自动:AUTO
setNeedClip: true, // 录制 设置是否需要支持片段录制
setMaxDuration: 15, // 录制 设置最大录制时长 单位秒
setMinDuration: 2, // 录制 设置最小录制时长 单位秒
setVideoQuality: 'HD', // 录制设置视频质量 4个级别, 低:LD ,中:SD ,高:HD ,极高:SSD
setGop: 125, // 设置关键帧间隔,建议:1-300之间
setMinVideoDuration: 5, // 裁剪 设置过滤的视频最小长度 单位秒
setMaxVideoDuration: 15, // 裁剪 设置过滤的视频最大长度 单位秒
setMinCropDuration: 2, // 裁剪 设置视频最小裁剪时间 单位毫秒
setFrameRate: 25, // 裁剪 设置帧率
setNeedRecord: false, // 设置是否需要开放录制入口,即选择视频的页面,多出一个录制按钮
setResulutionMode: '540p', // 设置裁剪分辨率,目前支持360p,480p,540p,720p
setCropMode: 'cpu' // 设置裁剪方式,是否使用gpu进行裁剪,不设置则默认使用cpu来裁剪
}

var recordVideoIos = new RecordVideoIos(option)
if (plus.os.name != 'Android') {
window.plus.recordVideo = recordVideoIos
}

就这么多了,不懂的可以加群864017187(dcloud混合开发交流群)

继续阅读 »

要想实现更多功能 适应更多应用场景 肯定是要选择离线打包的

1.基础版: 只有录制和裁剪功能,

  1. 标准版:可以修改UI
  2. 专业版: 很复杂的功能

可以参考,阿里云SDK说明

阿里云短视频基础版

如何没有离线打包过的,可以参考,官方最新的AS 打包教程:
ios离线打包教程

第一步
先下载ios短视频基础版SDK,详见sdk下载页面
1.开发者打开工程,选中目标target,依次选择”General”->”Embededed Binaries”,点击”+”号,点击“Add Other…”,导入QUCore-ThirdParty.framework和AliyunVideoSDK.framework。
2.同时,还需依赖libz.tbd、libc++.tbd、libiconv.tbd、libresolv.tbd、ImageIO.framework、CoreMedia.framework、CoreVideo.framework、SystemConfiguration.framework、Photos.framework、OpenAL.framework、VideoToolbox.framework请一并加上。截图如下

3.配置 Build Setting -- Build Options -- Enable Bitcode 选项为NO

4.配置 Build Setting -- Linking -- Other Linker Flags 添加 -ObjC选项

第二步
1.在HBuilder-Hello下新建文件夹recoredVideo 并在该文件夹下新建RecordVideo.h和RecordVideo.m文件

2.RecordVideo.h代码

include "PGPlugin.h"

include "PGMethod.h"

import <AliyunVideoSDK/AliyunVideoBase.h>

@interface RecordVideo : PGPlugin

  • (void)record:(PGMethod*)commands;
  • (void)videoBase:(AliyunVideoBase )base recordCompeleteWithRecordViewController:(UIViewController )recordVC videoPath:(NSString )videoPath;
    -(NSString
    )getNowTimeTimestamp;
    @end

3.RecordVideo.m代码

import "RecordVideo.h"

import <AliyunVideoSDK/AliyunVideoSDK.h>

import <AliyunVideoSDK/AliyunVideoRecordParam.h>

import <AliyunVideoSDK/AliyunVideoUIConfig.h>

import <AliyunVideoSDK/AliyunVideoBase.h>

import <AliyunVideoSDK/AliyunVideoCropParam.h>

import <AssetsLibrary/AssetsLibrary.h>

@interface RecordVideo()
@property (nonatomic,strong) NSString *callFunc;
@end

@implementation RecordVideo

  • (void)record:(PGMethod)commands
    {
    AliyunVideoUIConfig
    config = [[AliyunVideoUIConfig alloc] init];
    config.hiddenFlashButton = NO;
    config.imageBundleName = @"QPSDK";
    config.hiddenImportButton = YES;
    [[AliyunVideoBase shared] registerWithAliyunIConfig:config];

    NSString parameter0 = [commands.arguments objectAtIndex:0];
    self.callFunc = [commands.arguments objectAtIndex:1];
    NSData
    data= [parameter0 dataUsingEncoding:NSUTF8StringEncoding];
    NSError error = nil;
    id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
    NSDictionary
    dict = (NSDictionary )jsonObject;
    AliyunVideoRecordParam
    quVideo = [[AliyunVideoRecordParam alloc] init];
    quVideo.maxDuration = [[dict objectForKey:@"setMaxDuration"] doubleValue];
    quVideo.minDuration = [[dict objectForKey:@"setMinDuration"] doubleValue];
    quVideo.videoQuality = AliyunVideoQualityHight;
    quVideo.torchMode = AliyunCameraTorchModeOff;
    quVideo.size = AliyunVideoVideoSize540P;
    quVideo.gop = [[dict objectForKey:@"setGop"] intValue];
    quVideo.beautifyStatus = [[dict objectForKey:@"setBeautyStatus"] boolValue];
    quVideo.beautifyValue = [[dict objectForKey:@"setBeautyLevel"] intValue];
    quVideo.position = AliyunCameraPositionBack;
    NSString path = [NSTemporaryDirectory() stringByAppendingPathComponent:[[self getNowTimeTimestamp] stringByAppendingString: @".mp4"]];
    quVideo.outputPath = path;
    UIViewController
    recordViewController = [[AliyunVideoBase shared] createRecordViewControllerWithRecordParam:quVideo];
    [AliyunVideoBase shared].delegate = (id)self;
    [self.rootViewController.navigationController pushViewController:recordViewController animated:YES];
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    }

  • (void)videoBase:(AliyunVideoBase )base recordCompeleteWithRecordViewController:(UIViewController )recordVC videoPath:(NSString )videoPath {
    NSLog(@"录制完成 %@", videoPath);
    ALAssetsLibrary
    library = [[ALAssetsLibrary alloc] init];
    [library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:videoPath]
    completionBlock:^(NSURL assetURL, NSError error) {
    NSString path = [@"file://" stringByAppendingPathComponent:videoPath];
    NSDictionary
    dict = [NSDictionary dictionaryWithObjectsAndKeys:@"000000",@"code",path,@"path",nil];
    PDRPluginResult *result = [PDRPluginResult resultWithStatus:PDRCommandStatusOK messageAsDictionary:dict];
    [self toCallback:self.callFunc withReslut:[result toJSONString]];
    dispatch_async(dispatch_get_main_queue(), ^{
    [recordVC.navigationController popViewControllerAnimated:YES];
    });
    }];
    }

-(void)videoBaseRecordVideoExit {
NSLog(@"退出录制");
[self.rootViewController.navigationController popViewControllerAnimated:YES];
}

-(NSString *)getNowTimeTimestamp{

NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;  

[formatter setDateStyle:NSDateFormatterMediumStyle];  

[formatter setTimeStyle:NSDateFormatterShortStyle];  

[formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // ------ ----设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制  

//设置时区,这个对于时间的处理有时很重要  

NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];  

[formatter setTimeZone:timeZone];  

NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式  

NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];  

return timeSp;  

}
@end

第三步
1.打开PandoraApi.bundle下的feature.plist文件

2.feature.plist文件里加入
<key>RecordVideo</key>
<dict>
<key>class</key>
<string>RecordVideo</string>
<key>global</key>
<true/>
<key>autostart</key>
<string>YES</string>
</dict>

然后在html 页面 用JS通过 Native.js,调用原生类
var RecordVideoIos = function (options) {
this.options = this.extend(
{
setResolutionMode: '540p', // 录制 设置录制分辨率,目前支持360p,480p,540p,720p
setRatioMode: '1/1', // 录制 设置视频比例,目前支持1/1 ,3/4, 9/16
setRecordMode: 'AUTO', // 录制 设置录制模式,目前支持按录:PRESS,点录:TOUCH和混合模式:AUTO
setBeautyLevel: 80, // 录制 设置美颜度,1-100,比率
setBeautyStatus: true, // 录制 设置美颜开关
setCameraType: 'BACK', // 录制 设置前后置摄像头, 后:BACK ,前:FRONT
setFlashType: 'NO', // 录制 设置闪光灯模式,开:NO, 关:OFF, 自动:AUTO
setNeedClip: true, // 录制 设置是否需要支持片段录制
setMaxDuration: 15, // 录制 设置最大录制时长 单位秒
setMinDuration: 2, // 录制 设置最小录制时长 单位秒
setVideoQuality: 'HD', // 录制设置视频质量 4个级别, 低:LD ,中:SD ,高:HD ,极高:SSD
setGop: 125, // 设置关键帧间隔,建议:1-300之间
setMinVideoDuration: 5, // 裁剪 设置过滤的视频最小长度 单位秒
setMaxVideoDuration: 15, // 裁剪 设置过滤的视频最大长度 单位秒
setMinCropDuration: 2, // 裁剪 设置视频最小裁剪时间 单位毫秒
setFrameRate: 25, // 裁剪 设置帧率
setNeedRecord: false, // 设置是否需要开放录制入口,即选择视频的页面,多出一个录制按钮
setResulutionMode: '540p', // 设置裁剪分辨率,目前支持360p,480p,540p,720p
setCropMode: 'cpu' // 设置裁剪方式,是否使用gpu进行裁剪,不设置则默认使用cpu来裁剪
}, options)
this.init()
}

RecordVideoIos.prototype = {
init: function () {
this.event()
},
event: function () {
},
extend: function (obj, obj2) {
for (var k in obj2) {
obj[k] = obj2[k]
}
return obj
},
open: function (fn) {
let B = window.plus.bridge
let success = typeof fn !== 'function' ? null : function (args) {
fn(args)
}
let callbackID = B.callbackId(success, null)
return B.exec('RecordVideo', 'record', [JSON.stringify(this.options), callbackID])
}
}

const option = {
setResolutionMode: '720p', // 录制 设置录制分辨率,目前支持360p,480p,540p,720p
setRatioMode: '1/1', // 录制 设置视频比例,目前支持1/1 ,3/4, 9/16
setRecordMode: 'AUTO', // 录制 设置录制模式,目前支持按录:PRESS,点录:TOUCH和混合模式:AUTO
setBeautyLevel: 60, // 录制 设置美颜度,1-100,比率
setBeautyStatus: true, // 录制 设置美颜开关
setCameraType: 'BACK', // 录制 设置前后置摄像头, 后:BACK ,前:FRONT
setFlashType: 'OFF', // 录制 设置闪光灯模式,开:NO, 关:OFF, 自动:AUTO
setNeedClip: true, // 录制 设置是否需要支持片段录制
setMaxDuration: 15, // 录制 设置最大录制时长 单位秒
setMinDuration: 2, // 录制 设置最小录制时长 单位秒
setVideoQuality: 'HD', // 录制设置视频质量 4个级别, 低:LD ,中:SD ,高:HD ,极高:SSD
setGop: 125, // 设置关键帧间隔,建议:1-300之间
setMinVideoDuration: 5, // 裁剪 设置过滤的视频最小长度 单位秒
setMaxVideoDuration: 15, // 裁剪 设置过滤的视频最大长度 单位秒
setMinCropDuration: 2, // 裁剪 设置视频最小裁剪时间 单位毫秒
setFrameRate: 25, // 裁剪 设置帧率
setNeedRecord: false, // 设置是否需要开放录制入口,即选择视频的页面,多出一个录制按钮
setResulutionMode: '540p', // 设置裁剪分辨率,目前支持360p,480p,540p,720p
setCropMode: 'cpu' // 设置裁剪方式,是否使用gpu进行裁剪,不设置则默认使用cpu来裁剪
}

var recordVideoIos = new RecordVideoIos(option)
if (plus.os.name != 'Android') {
window.plus.recordVideo = recordVideoIos
}

就这么多了,不懂的可以加群864017187(dcloud混合开发交流群)

收起阅读 »

打开文件(ctrl+o)最好默认打开当前文件目录

打开文件(ctrl+o)最好默认打开当前文件目录, 这样特方便

打开文件(ctrl+o)最好默认打开当前文件目录, 这样特方便

GraceUI6.0 正式发布

uniapp graceUI

2022年06月13日 GraceUI 6.0 版本正式发布

GraceUI 是一款成熟完善的、为uni-app量身打造的优秀的UI框架!经过近4年的维护已经成为组件多、界面丰富、运行稳定的 uni-app 专业UI框架 !
GraceUI 第一版发布于2018年9月,4年多来我们一直坚持收集反馈,高效、高频更新!从1.0到6.0 GraceUI 已经变得更加丰富、兼容性更好~
在此也感谢近万名使用者的一路相伴,感谢你们的支持与反馈~
官网 : https://www.graceui.com/

1. 丰富的组件及样式

GraceUI 的组件、样式、布局、界面非常丰富,总量 150+!您可以使用他们快速的完成应用页面的布局~

1.1 基础布局组件及样式

页面布局 · Flex布局 · 元素定位 · 文本颜色 · 背景样式 · 阴影效果 · 圆角边框 · 文本样式 · 内置图标 · 样式动画

1.2 常用布局

宫格布局 · 头部导航 · 底部导航 · 切换导航 · 吸顶容器 · 动态吸顶 · 通用列表 · 滑动列表 · 新闻列表 · 评论列表 · 图文卡片 · 名片卡片 · 滚动区域 · 遮罩弹层 · 局部选项卡 · 全屏选项卡 · 分段切换 · 折叠面板 · 普通表格 · 数据表格 · 分类展示 · 横向公告 · 返回顶部 · 弹出菜单 · 功能菜单 · 时间轴 · 侧边抽屉 · 图标分类 · 横向日期

1.3 加载组件

加载组件 · 全屏加载 · 下拉刷新 · 刷新组件 · 上拉加载

1.4 常用组件

徽章组件 · 标签组件 · 滚动公告 · 无缝滚动 · 按钮组件 · 进度按钮 · 搜索组件 · 星级评价 · 通用标题 · 倒计时 · 轮播组件 · 日历时间 · 区间滑块 · 进度圆环 · 城市选择 · 地区联动 · 步骤提示 · 链接组件 · 优惠券组件 · 为空展示 · 图片选择 · 多图上传 · 头像群组 · 数值动画 · 日期时间选择 · 时间段选择器

1.5 对话框组件

顶部消息框 · 模态对话框 · 底部对话框 · 底部消息框

1.6 表单相关

表单元素 · 表单验证 · 数值框 · 数字键盘 · 可选标签 · 点选按钮 · 下拉选择

1.7 文章相关

文本编辑器 · 编辑器解析 · 富文本加强 · 展开全文

1.8 JS 工具库

时间转换 · 网络请求 · 随机数值 · md5转换 · 系统信息

1.9 常用界面库

搜索界面 · 登录注册 · 个人中心 · 购物车 · 订单中心 · 图片剪裁 · 商品详情 · 图片懒加载 · 骨架加载 · 抽奖活动 · 瀑布流 · 选择问卷 · 地址列表 · 添加地址 · 证件上传 · 滚动推荐 · 短信验证 · 排行榜 · 商城套装 · 即时通讯

2. 强大的版本支持 业界首款成熟的基于uni-app 的 nvue UI 框架

GraceUI 6.0 基于 vue3.0 同时支持 nvue,为app端更流畅的体验提供了极大的便利~
nvue 普通版本基本同步,想优化您的app?添加一个 .nuve 复制 vue 代码即可迅速完成~

3. 更好的兼容性、更稳定

GraceUI 自发布以来已经有上万名使用者,在开发的过程中不断给我们最真实的反馈,我们更是以积极的心态面对每一个反馈,及时确认问题并及时修正(最快10分钟哦)~经过一年多的 "锤炼",GraceUI 变得极度稳定、兼容性极好~ 感谢每一份反馈,感谢每一位支持者~

您不需要费力的去布局,有 GraceUI 就够了 ^_^

4. Grace.JS 化繁为简,只为热爱 ~

Grace.js 是 GraceUI 框架的 js 框架,目标是 " 简化您的 uni-app 及 微信小程序 api 操作,同时提供丰富、好用的 js 工具,大幅度提高您的开发效率" 。

5. 收费说明

GraceUI 6.0 版本售价 299元
收费只是最基本的维护开销,不是"赚钱的买卖",我们更认为是您的一种信任,对于我们更多的是责任!所以这里不是淘宝,不是简单的交易!我们希望得到正向的反馈、正向的帮助,不断完善,最终成为"组件多、稳定性好" 的UI框架!
一次性收费永久免费更新 ~

官网 :

https://www.graceui.com/

继续阅读 »

2022年06月13日 GraceUI 6.0 版本正式发布

GraceUI 是一款成熟完善的、为uni-app量身打造的优秀的UI框架!经过近4年的维护已经成为组件多、界面丰富、运行稳定的 uni-app 专业UI框架 !
GraceUI 第一版发布于2018年9月,4年多来我们一直坚持收集反馈,高效、高频更新!从1.0到6.0 GraceUI 已经变得更加丰富、兼容性更好~
在此也感谢近万名使用者的一路相伴,感谢你们的支持与反馈~
官网 : https://www.graceui.com/

1. 丰富的组件及样式

GraceUI 的组件、样式、布局、界面非常丰富,总量 150+!您可以使用他们快速的完成应用页面的布局~

1.1 基础布局组件及样式

页面布局 · Flex布局 · 元素定位 · 文本颜色 · 背景样式 · 阴影效果 · 圆角边框 · 文本样式 · 内置图标 · 样式动画

1.2 常用布局

宫格布局 · 头部导航 · 底部导航 · 切换导航 · 吸顶容器 · 动态吸顶 · 通用列表 · 滑动列表 · 新闻列表 · 评论列表 · 图文卡片 · 名片卡片 · 滚动区域 · 遮罩弹层 · 局部选项卡 · 全屏选项卡 · 分段切换 · 折叠面板 · 普通表格 · 数据表格 · 分类展示 · 横向公告 · 返回顶部 · 弹出菜单 · 功能菜单 · 时间轴 · 侧边抽屉 · 图标分类 · 横向日期

1.3 加载组件

加载组件 · 全屏加载 · 下拉刷新 · 刷新组件 · 上拉加载

1.4 常用组件

徽章组件 · 标签组件 · 滚动公告 · 无缝滚动 · 按钮组件 · 进度按钮 · 搜索组件 · 星级评价 · 通用标题 · 倒计时 · 轮播组件 · 日历时间 · 区间滑块 · 进度圆环 · 城市选择 · 地区联动 · 步骤提示 · 链接组件 · 优惠券组件 · 为空展示 · 图片选择 · 多图上传 · 头像群组 · 数值动画 · 日期时间选择 · 时间段选择器

1.5 对话框组件

顶部消息框 · 模态对话框 · 底部对话框 · 底部消息框

1.6 表单相关

表单元素 · 表单验证 · 数值框 · 数字键盘 · 可选标签 · 点选按钮 · 下拉选择

1.7 文章相关

文本编辑器 · 编辑器解析 · 富文本加强 · 展开全文

1.8 JS 工具库

时间转换 · 网络请求 · 随机数值 · md5转换 · 系统信息

1.9 常用界面库

搜索界面 · 登录注册 · 个人中心 · 购物车 · 订单中心 · 图片剪裁 · 商品详情 · 图片懒加载 · 骨架加载 · 抽奖活动 · 瀑布流 · 选择问卷 · 地址列表 · 添加地址 · 证件上传 · 滚动推荐 · 短信验证 · 排行榜 · 商城套装 · 即时通讯

2. 强大的版本支持 业界首款成熟的基于uni-app 的 nvue UI 框架

GraceUI 6.0 基于 vue3.0 同时支持 nvue,为app端更流畅的体验提供了极大的便利~
nvue 普通版本基本同步,想优化您的app?添加一个 .nuve 复制 vue 代码即可迅速完成~

3. 更好的兼容性、更稳定

GraceUI 自发布以来已经有上万名使用者,在开发的过程中不断给我们最真实的反馈,我们更是以积极的心态面对每一个反馈,及时确认问题并及时修正(最快10分钟哦)~经过一年多的 "锤炼",GraceUI 变得极度稳定、兼容性极好~ 感谢每一份反馈,感谢每一位支持者~

您不需要费力的去布局,有 GraceUI 就够了 ^_^

4. Grace.JS 化繁为简,只为热爱 ~

Grace.js 是 GraceUI 框架的 js 框架,目标是 " 简化您的 uni-app 及 微信小程序 api 操作,同时提供丰富、好用的 js 工具,大幅度提高您的开发效率" 。

5. 收费说明

GraceUI 6.0 版本售价 299元
收费只是最基本的维护开销,不是"赚钱的买卖",我们更认为是您的一种信任,对于我们更多的是责任!所以这里不是淘宝,不是简单的交易!我们希望得到正向的反馈、正向的帮助,不断完善,最终成为"组件多、稳定性好" 的UI框架!
一次性收费永久免费更新 ~

官网 :

https://www.graceui.com/

收起阅读 »

支付宝接口调用经验分享

支付宝这里,mui + plus+ 的api调用,会遇到很多的问题,下面是实际遇到的一些前提:

  1. 官网demo 给出的服务器 版本是 老版本的 支付宝服务api
  2. 官网给出的git 服务器版本项目中,有新版本,老版本两个版本的api都有
  3. 实际在测试过程中,可能使用的是沙箱账号或者是真实生产账号

最基本的部分我这里就不提了,出现异常的会有这几个部分,也就是你无论如何都找不到什么错误,但他偏偏错了的时候,可以参考下这几个原因:

  1. 如果使用沙箱账号,是无论如何都不会成功的。。我后来考虑应该是 plus.payment.request 这里是调用的正式支付宝的服务器,除非这里也提供一个沙箱服务器调用的版本,否则两者就相当于一个用正式服务器,一个用沙箱服务器,完全两套东西。。。注意: 支付宝的沙箱和正式生产服务器是两个不同的地址
  2. 使用沙箱账号的时候,可能报多种错误: [payment支付宝:62001]用户中途取消支付操作 ;; [payment支付宝:62009]未知错误;
继续阅读 »

支付宝这里,mui + plus+ 的api调用,会遇到很多的问题,下面是实际遇到的一些前提:

  1. 官网demo 给出的服务器 版本是 老版本的 支付宝服务api
  2. 官网给出的git 服务器版本项目中,有新版本,老版本两个版本的api都有
  3. 实际在测试过程中,可能使用的是沙箱账号或者是真实生产账号

最基本的部分我这里就不提了,出现异常的会有这几个部分,也就是你无论如何都找不到什么错误,但他偏偏错了的时候,可以参考下这几个原因:

  1. 如果使用沙箱账号,是无论如何都不会成功的。。我后来考虑应该是 plus.payment.request 这里是调用的正式支付宝的服务器,除非这里也提供一个沙箱服务器调用的版本,否则两者就相当于一个用正式服务器,一个用沙箱服务器,完全两套东西。。。注意: 支付宝的沙箱和正式生产服务器是两个不同的地址
  2. 使用沙箱账号的时候,可能报多种错误: [payment支付宝:62001]用户中途取消支付操作 ;; [payment支付宝:62009]未知错误;
收起阅读 »

高性能手机app前端开发Hello MUI框架模板

hellomui mui

一款高性能手机app前端开发Hello MUI框架模板,MUI不依赖任何第三方JS库,压缩后的JS和CSS文件仅有100+K和60+K。MUI以iOS平台UI为基础,补充部分Android平台特有的UI控件。

下载地址:http://www.sucaihuo.com/templates/3694.html
更多MUI模板:http://www.sucaihuo.com/search.html?keyword=mui&mtype=1

继续阅读 »

一款高性能手机app前端开发Hello MUI框架模板,MUI不依赖任何第三方JS库,压缩后的JS和CSS文件仅有100+K和60+K。MUI以iOS平台UI为基础,补充部分Android平台特有的UI控件。

下载地址:http://www.sucaihuo.com/templates/3694.html
更多MUI模板:http://www.sucaihuo.com/search.html?keyword=mui&mtype=1

收起阅读 »

郑州app制作的常见开发模式都分哪些呢

5 App开发 移动APP

  可以看到,在每一天不管是个人来讲还是单位来讲都有许许多多的郑州app制作和郑州app定制的需求,面对这些大量的制作需求,在现实当中可以采用两种不同的方式来进行制作,不同的方式当然具有不同的特点和优势,下面就来详细的跟大家分析解答一下吧。

  一、找专业开发公司

  如果在实际制作的过程当中,选择了这样的一种制作方式,那么就可以更加的省事了。因为选择这样的一种制作方式专业开发公司会为我们提供一整套的完整的解决方案。这一整套的方案不仅仅包括了前期的市场调查以及用户调研,还包括了手机app的整个设计方案,整个功能的设计分布,如何实现客户的目标功能,而且还包括了手机app制作完成之后的一些后期的推广和宣传工作。

  在进行完了这一系列的工作之后,专业开发公司还会根据他们的工作情况来为计算出一个制作的价格,根据所制作手机app的具体情况,项目的复杂程度,制作的价格会在几十万到几百万不等,不管怎样,选择这种制作方式都是非常的方便快捷的,只需要等待成果的验收情况即可。

  二、团队项目整体承包的方式

  这样的一种方式在目前也是采用得比较多的一种方式,这种方式一般都是设计师与开发工程师来共同合作完成的,采用这样的一种制作方式也会为我们提供一整套的设计解决方案,但是采用这样的一种方式在前期调研和后期的推广方面不会有。一般来说都会按照整体的风格设计报价加上各个功能模块的嵌入整合为一个整体的报价。采用这样的一种方式一般的制作费用大概是在几万到几十万元不等,具体的价格要根据手机app的具体制作难易程度来进行确定。

  一般来说,海外的一些开发者和设计师们他们都更倾向与采用时薪的方法来计算制作的整体费用,但采用这样的一种方式无疑会增加制作的整体成本,因此国内的一些客户们并不喜欢这样的一种计算价格的方式,一般也不会选择这样的方式来计算制作总体价格。
本文由专业的郑州app开发公司燚轩科技整理发布,如需转载请注明出处。

继续阅读 »

  可以看到,在每一天不管是个人来讲还是单位来讲都有许许多多的郑州app制作和郑州app定制的需求,面对这些大量的制作需求,在现实当中可以采用两种不同的方式来进行制作,不同的方式当然具有不同的特点和优势,下面就来详细的跟大家分析解答一下吧。

  一、找专业开发公司

  如果在实际制作的过程当中,选择了这样的一种制作方式,那么就可以更加的省事了。因为选择这样的一种制作方式专业开发公司会为我们提供一整套的完整的解决方案。这一整套的方案不仅仅包括了前期的市场调查以及用户调研,还包括了手机app的整个设计方案,整个功能的设计分布,如何实现客户的目标功能,而且还包括了手机app制作完成之后的一些后期的推广和宣传工作。

  在进行完了这一系列的工作之后,专业开发公司还会根据他们的工作情况来为计算出一个制作的价格,根据所制作手机app的具体情况,项目的复杂程度,制作的价格会在几十万到几百万不等,不管怎样,选择这种制作方式都是非常的方便快捷的,只需要等待成果的验收情况即可。

  二、团队项目整体承包的方式

  这样的一种方式在目前也是采用得比较多的一种方式,这种方式一般都是设计师与开发工程师来共同合作完成的,采用这样的一种制作方式也会为我们提供一整套的设计解决方案,但是采用这样的一种方式在前期调研和后期的推广方面不会有。一般来说都会按照整体的风格设计报价加上各个功能模块的嵌入整合为一个整体的报价。采用这样的一种方式一般的制作费用大概是在几万到几十万元不等,具体的价格要根据手机app的具体制作难易程度来进行确定。

  一般来说,海外的一些开发者和设计师们他们都更倾向与采用时薪的方法来计算制作的整体费用,但采用这样的一种方式无疑会增加制作的整体成本,因此国内的一些客户们并不喜欢这样的一种计算价格的方式,一般也不会选择这样的方式来计算制作总体价格。
本文由专业的郑州app开发公司燚轩科技整理发布,如需转载请注明出处。

收起阅读 »

MUI Checkbox使用官方例子报错

直接新建一个官方的HELLO MUI项目 打开checkbox例子,点击窗口无法使用,点击后就报这个错误:TypeError: c.detail.gesture.changedTouches is undefined

直接新建一个官方的HELLO MUI项目 打开checkbox例子,点击窗口无法使用,点击后就报这个错误:TypeError: c.detail.gesture.changedTouches is undefined

窗口打开网址,支持手势缩放

直接给解决办法。需要注意如果设置了meat禁止缩放,比如手机站,就不会生效

直接给解决办法。需要注意如果设置了meat禁止缩放,比如手机站,就不会生效

不使用uploader上传文件的方法

file uploader

最近公司要求统一http框架 需要脱离uploader改用普通的formdata上传文件,大体思路就是将plus的file对象转为blob然后重新生成符合formdata格式的file对象 代码如下:

function chooseFile(filter) {
var that = this;
plus.gallery.pick(function (path) {
plus.io.resolveLocalFileSystemURL(path, function (entry) {
entry.file(function (file) {
var reader = new plus.io.FileReader();
reader.onloadend = function (e) {
var file=(function (path,name) {
var arr = path.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], name, {type: mime});
})(e.target.result,entry.name);
var formData = new FormData();
formData.append("file", file);
that.upload(formData);
};
reader.readAsDataURL(file);
});
}, function (e) {
console.log(e)
});
}, function (e) {
console.log(e);
}, {filter: filter, system: true});
},

继续阅读 »

最近公司要求统一http框架 需要脱离uploader改用普通的formdata上传文件,大体思路就是将plus的file对象转为blob然后重新生成符合formdata格式的file对象 代码如下:

function chooseFile(filter) {
var that = this;
plus.gallery.pick(function (path) {
plus.io.resolveLocalFileSystemURL(path, function (entry) {
entry.file(function (file) {
var reader = new plus.io.FileReader();
reader.onloadend = function (e) {
var file=(function (path,name) {
var arr = path.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], name, {type: mime});
})(e.target.result,entry.name);
var formData = new FormData();
formData.append("file", file);
that.upload(formData);
};
reader.readAsDataURL(file);
});
}, function (e) {
console.log(e)
});
}, function (e) {
console.log(e);
}, {filter: filter, system: true});
},

收起阅读 »

如何集成iBeacon扫描,实现室内定位应用

iBeacon

注意:需使用最新版HBuilderX

概述

iBeacon基站是一种蓝牙设备,可以广播符合苹果提供的iBeacon协议,通过手持设备(如IOS/Android)硬件支持蓝牙4.0及以上,即可扫描iBeacon设备信号,其主要参数有UUID-通用标识、Major-主标识、Minor-次标识、RSSI-信号强度、accuracy-距离,通过这些基站讯息,可以轻松实现签到、室内定位、导航等应用场景

开始使用

引入iBeacon,参见API文档,即可开始扫描iBeacon:

plus.ibeacon.startBeaconDiscovery({uuids: ["fda50693-a4e2-4fb1-afcf-c6eb07647825"]});

室内定位场景体验

5+提供的iBeacon设备的支持,是底层api,不带室内定位业务。
需要使用与地图数据配套的iBeacon设备参数部署方案,才可以实现室内地图定位。体验本示例地图,需要使用以下iBeacon参数列表如下:(可以使用APP iBeacon模拟软件,或使用iBeacon硬件配置)

UUID FDA50693-A4E2-4FB1-AFCF-C6EB07647825
Major 10186
Minor 47997 、 47998 、47999 、 48000

地图、定位代码示例:

        <script type="text/javascript">  
            function startLocation() {  
                                //扫描指定UUID的iBeacon设备  
                plus.ibeacon.startBeaconDiscovery({uuids: ["fda50693-a4e2-4fb1-afcf-c6eb07647825"]});  
                                plus.ibeacon.onBeaconUpdate(function(result){  
                                                    if(result.beacons && result.beacons.length > 0) {  
                                                        //传人定位设备  
                                                        var win = document.getElementById("ifr").contentWindow;  
                                                        var params = {"key": "onSearchBeacons","value": result };  
                                                        win.postMessage(JSON.stringify(params), "*");  
                                                    }  
                                 });  
            }  
                       //退出场景,请及时停止扫描  
            function disappear() {  
                plus.ibeacon.stopBeaconDiscovery();  
            }  
        </script>  
    <body>  
        <iframe title="示例地图" id="ifr" src="http://p.brtbeacon.net/bb/crh/navigator.html?signa=9250019a13c24d969d445d1072685785" frameborder="no" scrolling="no" style="width: 100%;height: 100%;margin-top: 0px;border:0 none;frameborder:0;" onLoad="setTimeout(startLocation,3000)"></iframe>  
    </body>

使用你的地图

智石科技是DCloud的合作伙伴,可以提供室内地图服务。
获取你的地图参数

①前往智石开发者中心并登录

②首次注册用户需创建【应用AppKey】,即可申请试用地图

②登录查看你的【建筑列表】获取AppKey、【设备管理】获取UUID等参数,填入示例工程即可

商务合作、地图绘制咨询4000-999-023

继续阅读 »

注意:需使用最新版HBuilderX

概述

iBeacon基站是一种蓝牙设备,可以广播符合苹果提供的iBeacon协议,通过手持设备(如IOS/Android)硬件支持蓝牙4.0及以上,即可扫描iBeacon设备信号,其主要参数有UUID-通用标识、Major-主标识、Minor-次标识、RSSI-信号强度、accuracy-距离,通过这些基站讯息,可以轻松实现签到、室内定位、导航等应用场景

开始使用

引入iBeacon,参见API文档,即可开始扫描iBeacon:

plus.ibeacon.startBeaconDiscovery({uuids: ["fda50693-a4e2-4fb1-afcf-c6eb07647825"]});

室内定位场景体验

5+提供的iBeacon设备的支持,是底层api,不带室内定位业务。
需要使用与地图数据配套的iBeacon设备参数部署方案,才可以实现室内地图定位。体验本示例地图,需要使用以下iBeacon参数列表如下:(可以使用APP iBeacon模拟软件,或使用iBeacon硬件配置)

UUID FDA50693-A4E2-4FB1-AFCF-C6EB07647825
Major 10186
Minor 47997 、 47998 、47999 、 48000

地图、定位代码示例:

        <script type="text/javascript">  
            function startLocation() {  
                                //扫描指定UUID的iBeacon设备  
                plus.ibeacon.startBeaconDiscovery({uuids: ["fda50693-a4e2-4fb1-afcf-c6eb07647825"]});  
                                plus.ibeacon.onBeaconUpdate(function(result){  
                                                    if(result.beacons && result.beacons.length > 0) {  
                                                        //传人定位设备  
                                                        var win = document.getElementById("ifr").contentWindow;  
                                                        var params = {"key": "onSearchBeacons","value": result };  
                                                        win.postMessage(JSON.stringify(params), "*");  
                                                    }  
                                 });  
            }  
                       //退出场景,请及时停止扫描  
            function disappear() {  
                plus.ibeacon.stopBeaconDiscovery();  
            }  
        </script>  
    <body>  
        <iframe title="示例地图" id="ifr" src="http://p.brtbeacon.net/bb/crh/navigator.html?signa=9250019a13c24d969d445d1072685785" frameborder="no" scrolling="no" style="width: 100%;height: 100%;margin-top: 0px;border:0 none;frameborder:0;" onLoad="setTimeout(startLocation,3000)"></iframe>  
    </body>

使用你的地图

智石科技是DCloud的合作伙伴,可以提供室内地图服务。
获取你的地图参数

①前往智石开发者中心并登录

②首次注册用户需创建【应用AppKey】,即可申请试用地图

②登录查看你的【建筑列表】获取AppKey、【设备管理】获取UUID等参数,填入示例工程即可

商务合作、地图绘制咨询4000-999-023

收起阅读 »

郑州小程序开发模式和报价费用有关吗

微信小程序 小程序

  和郑州小程序开发公司打过交道的企业都知道,不同的开发公司对小程序开发的报价是有很大差异的。例如同样一款商城类小程序,有的报价可以低到几千,有的则报价至少两万。很多人不禁会质疑,为什么相同的小程序类型为什么价格差距如此大。其实一个小程序的开发包含了很多环节,每个环节的开发需求不同都会导致开发价格的天壤之别。下面来介绍一下关于微信小程序开发的付费模式。

  首先从小程序的付费模式来看,通常有两种方式:一是按年付费,也就是购买小程序模板。以模板销售为主的开发公司,会根据市场上行业的大致分类,按照行业的共同属性开发出一些具备该行业基础功能的模板,例如餐饮类、商城类等等。模板类的小程序购买后上线快,价格低,但是缺乏灵活度和创新度。

  二是定制付费版,即按照商家的开发需求进行定制开发,自然价格也是根据具体的开发需求而定,没有统一标准。所谓定制,就是开发公司的市场和产品经理以及技术人员,会根据每个商家不同的产品特征和需求,挖掘用户痛点,梳理开发需求,定制功能列表,并在产品交付后提供相关的产品培训服务。无论是界面还是功能,都是依据企业的品牌形象而匹配定制的。

  这种定制化的开发费用相对较高,均价都在万元以上,具体要依据功能需求来定。虽然定制开发的成本和周期都要略高,但同时小程序性能和用户体验度也更高。不同商家所面对的客户群体是不相同的,所以在开发小程序之前,一定要明确自己的产品定位和目标客户是谁,然后再有针对性的选择合适的开发公司。

  目前小程序开发市场还不是很成熟,所以导致不同开发公司对小程序开发的报价差异很大,从几千到几万的价格都有。因此,对于有需要开发小程序来拓展业务的商家来说,小程序的开发价格就显得很混乱,那么小程序开发到底什么样的报价是合理,只有先了解清楚行情在去找小程序开发公司才算是合理的。
本文由专业的郑州小程序开发公司燚轩科技整理发布,如需转载请注明出处!

继续阅读 »

  和郑州小程序开发公司打过交道的企业都知道,不同的开发公司对小程序开发的报价是有很大差异的。例如同样一款商城类小程序,有的报价可以低到几千,有的则报价至少两万。很多人不禁会质疑,为什么相同的小程序类型为什么价格差距如此大。其实一个小程序的开发包含了很多环节,每个环节的开发需求不同都会导致开发价格的天壤之别。下面来介绍一下关于微信小程序开发的付费模式。

  首先从小程序的付费模式来看,通常有两种方式:一是按年付费,也就是购买小程序模板。以模板销售为主的开发公司,会根据市场上行业的大致分类,按照行业的共同属性开发出一些具备该行业基础功能的模板,例如餐饮类、商城类等等。模板类的小程序购买后上线快,价格低,但是缺乏灵活度和创新度。

  二是定制付费版,即按照商家的开发需求进行定制开发,自然价格也是根据具体的开发需求而定,没有统一标准。所谓定制,就是开发公司的市场和产品经理以及技术人员,会根据每个商家不同的产品特征和需求,挖掘用户痛点,梳理开发需求,定制功能列表,并在产品交付后提供相关的产品培训服务。无论是界面还是功能,都是依据企业的品牌形象而匹配定制的。

  这种定制化的开发费用相对较高,均价都在万元以上,具体要依据功能需求来定。虽然定制开发的成本和周期都要略高,但同时小程序性能和用户体验度也更高。不同商家所面对的客户群体是不相同的,所以在开发小程序之前,一定要明确自己的产品定位和目标客户是谁,然后再有针对性的选择合适的开发公司。

  目前小程序开发市场还不是很成熟,所以导致不同开发公司对小程序开发的报价差异很大,从几千到几万的价格都有。因此,对于有需要开发小程序来拓展业务的商家来说,小程序的开发价格就显得很混乱,那么小程序开发到底什么样的报价是合理,只有先了解清楚行情在去找小程序开发公司才算是合理的。
本文由专业的郑州小程序开发公司燚轩科技整理发布,如需转载请注明出处!

收起阅读 »