iOS
//
// ViewController.swift
// uploadDemo
//
// Created by zack on 2017/8/21.
// Copyright © 2017年 zack. All rights reserved.
//
import UIKit
import AVFoundation
import MobileCoreServices
import AssetsLibrary
import AVKit
import Alamofire
import MediaPlayer
import SwiftyJSON
import PhotosUI
import Photos
class ViewController: UIViewController,UIImagePickerControllerDelegate, UINavigationControllerDelegate {
@IBOutlet weak var myImageV: UIImageView!
//设置标志,用于标识上传那种类型文件(图片/视频)
var flag = ""
//设置服务器地址
// let uploadURL = "http://localhost:63342/ajax/uploadFile/upload.php"
let uploadURL = "http://xxxxx/uploadFile/upload.php"
override func viewDidLoad() {
super.viewDidLoad()
}
//按钮事件:上传图片
@IBAction func uploadImage(_ sender: Any) {
photoLib()
}
//按钮事件:上传视频
@IBAction func uploadVideo(_ sender: Any) {
videoLib()
}
//图库 - 照片
func photoLib(){
//
flag = "图片"
//判断设置是否支持图片库
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary){
//初始化图片控制器
let picker = UIImagePickerController()
//设置代理
picker.delegate = self
//指定图片控制器类型
picker.sourceType = UIImagePickerControllerSourceType.photoLibrary
//弹出控制器,显示界面
self.present(picker, animated: true, completion: {
() -> Void in
})
}else{
print("读取相册错误")
}
}
//图库 - 视频
func videoLib(){
flag = "视频"
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
//初始化图片控制器
let imagePicker = UIImagePickerController()
//设置代理
imagePicker.delegate = self
//指定图片控制器类型
imagePicker.sourceType = .photoLibrary;
//只显示视频类型的文件
imagePicker.mediaTypes = [kUTTypeMovie as String]
//不需要编辑
imagePicker.allowsEditing = false
//弹出控制器,显示界面
self.present(imagePicker, animated: true, completion: nil)
}
else {
print("读取相册错误")
}
}
//选择成功后代理
func imagePickerController(_ picker: UIImagePickerController,didFinishPickingMediaWithInfo info: [String : Any]) {
if flag == "视频" {
//获取选取的视频路径
let videoURL = info[UIImagePickerControllerReferenceURL] as! URL
let fetchResult :PHFetchResult = PHAsset.fetchAssets(withALAssetURLs: [videoURL], options: nil)
fetchResult.enumerateObjects({ (phAsset, idx, nil) in
let options :PHVideoRequestOptions = PHVideoRequestOptions()
options.version = .current
let manager :PHImageManager = PHImageManager.default()
manager.requestAVAsset(forVideo: phAsset, options: options, resultHandler: { (asset, audioMix, info) in
let urlAsset:AVURLAsset = asset as! AVURLAsset;
let url :NSURL = urlAsset.url as NSURL;
print(url) //file:///var/mobile/Media/PhotoData/Metadata/PhotoData/CPLAssets/group337/66DB0587-A13C-4D8A-97E5-D9975DEF971F.medium.MP4
self.uploadVideo(mp4Path: url as URL)
})
})
self.dismiss(animated: true, completion: nil)
// let outpath = NSHomeDirectory() + "/Documents/\(Date().timeIntervalSince1970).mp4"
// //视频转码
// self.transformMoive(inputPath: pathString, outputPath: outpath)
}else{
//flag = "图片"
//获取选取后的图片
let pickedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
//转成jpg格式图片
guard let jpegData = UIImageJPEGRepresentation(pickedImage, 0.1) else {
return
}
self.myImageV.image = pickedImage
//上传
self.uploadImage(imageData: jpegData)
//图片控制器退出
self.dismiss(animated: true, completion:nil)
}
}
//上传图片到服务器
func uploadImage(imageData : Data){
Alamofire.upload(
multipartFormData: { multipartFormData in
//采用post表单上传
// 参数解释:
//withName:和后台服务器的name要一致 fileName:自己随便写,但是图片格式要写对 mimeType:规定的,要上传其他格式可以自行百度查一下
multipartFormData.append(imageData, withName: "file", fileName: "123456.png", mimeType: "image/jpeg")
//如果需要上传多个文件,就多添加几个
//multipartFormData.append(imageData, withName: "file", fileName: "123456.jpg", mimeType: "image/jpeg")
//......
},to: uploadURL,encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
//连接服务器成功后,对json的处理
upload.responseJSON { response in
//解包
guard let result = response.result.value else {
return
}
print("\(result)")
//须导入 swiftyJSON 第三方框架,否则报错
let message = JSON(result)["messsage"].stringValue
print(message)
if message == "1" {
print("上传成功")
let alert = UIAlertController(title:"提示",message:"上传成功", preferredStyle: .alert)
let action2 = UIAlertAction(title: "关闭", style: .default, handler: nil)
alert.addAction(action2)
self.present(alert , animated: true , completion: nil)
}else{
print("上传失败")
let alert = UIAlertController(title:"提示",message:"上传失败", preferredStyle: .alert)
let action2 = UIAlertAction(title: "关闭", style: .default, handler: nil)
alert.addAction(action2)
self.present(alert , animated: true , completion: nil)
}
}
//获取上传进度
upload.uploadProgress(queue: DispatchQueue.global(qos: .utility)) { progress in
print("图片上传进度: \(progress.fractionCompleted)")
}
case .failure(let encodingError):
//打印连接失败原因
print(encodingError)
}
})
}
//上传视频到服务器
func uploadVideo(mp4Path : URL){
Alamofire.upload(
//同样采用post表单上传
multipartFormData: { multipartFormData in
multipartFormData.append(mp4Path, withName: "file", fileName: "123456.mp4", mimeType: "video/mp4")
//服务器地址
},to: uploadURL,encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
//json处理
upload.responseJSON { response in
//解包
guard let result = response.result.value else { return }
print("\(result)")
//须导入 swiftyJSON 第三方框架,否则报错
// let message = JSON(result)["message"].int ?? -1
let message = JSON(result)["messsage"].stringValue
print(message)
if message == "1" {
print("上传成功")
let alert = UIAlertController(title:"提示",message:"上传成功", preferredStyle: .alert)
let action2 = UIAlertAction(title: "关闭", style: .default, handler: nil)
alert.addAction(action2)
self.present(alert , animated: true , completion: nil)
}else{
print("上传失败")
let alert = UIAlertController(title:"提示",message:"上传失败", preferredStyle: .alert)
let action2 = UIAlertAction(title: "关闭", style: .default, handler: nil)
alert.addAction(action2)
self.present(alert , animated: true , completion: nil)
}
}
//上传进度
upload.uploadProgress(queue: DispatchQueue.global(qos: .utility)) { progress in
print("视频上传进度: \(progress.fractionCompleted)")
}
case .failure(let encodingError):
print(encodingError)
}
})
}
/// 转换视频
///
/// - Parameters:
/// - inputPath: 输入url
/// - outputPath:输出url
func transformMoive(inputPath:String,outputPath:String){
let avAsset:AVURLAsset = AVURLAsset(url: URL.init(fileURLWithPath: inputPath), options: nil)
let assetTime = avAsset.duration
let duration = CMTimeGetSeconds(assetTime)
print("视频时长 \(duration)");
let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: avAsset)
if compatiblePresets.contains(AVAssetExportPresetLowQuality) {
let exportSession:AVAssetExportSession = AVAssetExportSession.init(asset: avAsset, presetName: AVAssetExportPresetMediumQuality)!
let existBool = FileManager.default.fileExists(atPath: outputPath)
if existBool {
}
exportSession.outputURL = URL.init(fileURLWithPath: outputPath)
exportSession.outputFileType = AVFileTypeMPEG4
exportSession.shouldOptimizeForNetworkUse = true;
exportSession.exportAsynchronously(completionHandler: {
switch exportSession.status{
case .failed:
print("失败...\(String(describing: exportSession.error?.localizedDescription))")
break
case .cancelled:
print("取消")
break;
case .completed:
print("转码成功")
//转码成功后获取视频视频地址
let mp4Path = URL.init(fileURLWithPath: outputPath)
//上传
self.uploadVideo(mp4Path: mp4Path)
break;
default:
print("..")
break;
}
})
}
}
}
php
<?php
header('Content-type: text/json; charset=UTF-8' );
/**
* $_FILES 文件上传变量,是一个二维数组,第一维保存上传的文件的数组,第二维保存文件的属性,包括类型、大小等
* 要实现上传文件,必须修改权限为加入可写 chmod -R 777 目标目录
*/
error_reporting(ALL);
// 文件类型限制
// "file"名字必须和iOS客户端上传的name一致
if (($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/png")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "video/mp4"))
// && ($_FILES["file"]["size"] < 20000)) // 小于20k
{
if ($_FILES["file"]["error"] > 0) {
echo $_FILES["file"]["error"]; // 错误代码
} else {
$fillname = $_FILES['file']['name']; // 得到文件全名
$dotArray = explode('.', $fillname); // 以.分割字符串,得到数组
$type = end($dotArray); // 得到最后一个元素:文件后缀
$dir = iconv("UTF-8", "GBK", "./pics");
if (!file_exists($dir)){
mkdir ($dir,0777,true);
// echo '创建文件夹bookcover成功';
} else {
// echo '需创建的文件夹bookcover已经存在';
}
$path = "./pics/".md5(uniqid(rand())).'.'.$type; // 产生随机唯一的名字
move_uploaded_file( // 从临时目录复制到目标目录
$_FILES["file"]["tmp_name"], // 存储在服务器的文件的临时副本的名称
$path);
$arry = array( 'messsage' => "1");
fclose($myfile);
echo json_encode($arry);
}
} else {
echo "文件类型不正确";
}
?>