mirror of
https://github.com/wahyd4/Yep.git
synced 2026-08-19 09:46:56 +10:00
sendVideo
This commit is contained in:
@@ -126,6 +126,7 @@
|
||||
50E114F91ABC137A00F13000 /* YepServiceSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E114F81ABC137A00F13000 /* YepServiceSync.swift */; };
|
||||
50E114FC1ABC549300F13000 /* ContactsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E114FA1ABC549300F13000 /* ContactsCell.swift */; };
|
||||
50E114FD1ABC549300F13000 /* ContactsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 50E114FB1ABC549300F13000 /* ContactsCell.xib */; };
|
||||
50EB8C5E1AE78AB9001AC1EE /* YepAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50EB8C5D1AE78AB9001AC1EE /* YepAsset.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -266,6 +267,7 @@
|
||||
50E114F81ABC137A00F13000 /* YepServiceSync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepServiceSync.swift; path = Services/YepServiceSync.swift; sourceTree = "<group>"; };
|
||||
50E114FA1ABC549300F13000 /* ContactsCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ContactsCell.swift; path = Views/Cells/Contacts/ContactsCell.swift; sourceTree = "<group>"; };
|
||||
50E114FB1ABC549300F13000 /* ContactsCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = ContactsCell.xib; path = Views/Cells/Contacts/ContactsCell.xib; sourceTree = "<group>"; };
|
||||
50EB8C5D1AE78AB9001AC1EE /* YepAsset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepAsset.swift; path = Helpers/YepAsset.swift; sourceTree = "<group>"; };
|
||||
B33BE6A6016453F6673C8317 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
|
||||
FD88F6095DB46DFAD41AB5DB /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -608,6 +610,7 @@
|
||||
children = (
|
||||
502AE5391AB871C1005BD199 /* YepAlert.swift */,
|
||||
502AE53C1AB87C0D005BD199 /* YepUserDefaults.swift */,
|
||||
50EB8C5D1AE78AB9001AC1EE /* YepAsset.swift */,
|
||||
);
|
||||
name = Helpers;
|
||||
sourceTree = "<group>";
|
||||
@@ -1101,6 +1104,7 @@
|
||||
50E114F41ABBF9CC00F13000 /* Models.swift in Sources */,
|
||||
50A9D4571ACD393A000B2599 /* YepWaverView.swift in Sources */,
|
||||
50165C451AC2860900C7AEBE /* ConversationLayout.swift in Sources */,
|
||||
50EB8C5E1AE78AB9001AC1EE /* YepAsset.swift in Sources */,
|
||||
508C2AA41AD661B3002B8097 /* UserStateCell.swift in Sources */,
|
||||
0A5D83941AC5D3C8000045BF /* YepTabBarController.swift in Sources */,
|
||||
50E114FC1ABC549300F13000 /* ContactsCell.swift in Sources */,
|
||||
|
||||
@@ -108,4 +108,26 @@ extension NSFileManager {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Video
|
||||
|
||||
class func yepMessageVideoURLWithName(name: String) -> NSURL? {
|
||||
|
||||
if let messageCachesURL = yepMessageCachesURL() {
|
||||
return messageCachesURL.URLByAppendingPathComponent("\(name).mp4")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
class func saveMessageVideoData(messageVideoData: NSData, withName name: String) -> NSURL? {
|
||||
|
||||
if let messageVideoURL = yepMessageVideoURLWithName(name) {
|
||||
if NSFileManager.defaultManager().createFileAtPath(messageVideoURL.path!, contents: messageVideoData, attributes: nil) {
|
||||
return messageVideoURL
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// YepAsset.swift
|
||||
// Yep
|
||||
//
|
||||
// Created by NIX on 15/4/22.
|
||||
// Copyright (c) 2015年 Catch Inc. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AVFoundation
|
||||
|
||||
func thumbnailImageOfVideoInVideoURL(videoURL: NSURL) -> UIImage? {
|
||||
let asset = AVURLAsset(URL: videoURL, options: [:])
|
||||
let imageGenerator = AVAssetImageGenerator(asset: asset)
|
||||
|
||||
imageGenerator.appliesPreferredTrackTransform = true
|
||||
|
||||
var actualTime: CMTime = CMTimeMake(0, 0)
|
||||
var error: NSError?
|
||||
|
||||
let cgImage = imageGenerator.copyCGImageAtTime(CMTimeMakeWithSeconds(0.0, 600), actualTime: &actualTime, error: &error)
|
||||
|
||||
let thumbnail = UIImage(CGImage: cgImage)
|
||||
|
||||
return thumbnail
|
||||
}
|
||||
@@ -777,6 +777,11 @@ func sendAudioInFilePath(filePath: String?, orFileData fileData: NSData?, #metaD
|
||||
sendMessageWithMediaType(.Audio, inFilePath: filePath, orFileData: fileData, metaData: metaData, text: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
}
|
||||
|
||||
func sendVideoInFilePath(filePath: String?, orFileData fileData: NSData?, #metaData: String?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) {
|
||||
|
||||
sendMessageWithMediaType(.Video, inFilePath: filePath, orFileData: fileData, metaData: metaData, text: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
}
|
||||
|
||||
func sendMessageWithMediaType(mediaType: MessageMediaType, inFilePath filePath: String?, orFileData fileData: NSData?, #metaData: String?, #text: String?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) {
|
||||
// 因为 message_id 必须来自远端,线程无法切换,所以这里暂时没用 realmQueue // TOOD: 也许有办法
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import UIKit
|
||||
import Realm
|
||||
import AVFoundation
|
||||
import MobileCoreServices
|
||||
|
||||
class ConversationViewController: UIViewController {
|
||||
|
||||
@@ -369,7 +370,9 @@ class ConversationViewController: UIViewController {
|
||||
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary){
|
||||
let imagePicker = UIImagePickerController()
|
||||
imagePicker.delegate = self
|
||||
imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
|
||||
imagePicker.sourceType = .PhotoLibrary
|
||||
imagePicker.mediaTypes = [kUTTypeImage, kUTTypeMovie]
|
||||
imagePicker.videoQuality = .TypeMedium
|
||||
imagePicker.allowsEditing = false
|
||||
|
||||
self.presentViewController(imagePicker, animated: true, completion: nil)
|
||||
@@ -380,7 +383,9 @@ class ConversationViewController: UIViewController {
|
||||
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera){
|
||||
let imagePicker = UIImagePickerController()
|
||||
imagePicker.delegate = self
|
||||
imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
|
||||
imagePicker.sourceType = .Camera
|
||||
imagePicker.mediaTypes = [kUTTypeImage, kUTTypeMovie]
|
||||
imagePicker.videoQuality = .TypeMedium
|
||||
imagePicker.allowsEditing = false
|
||||
|
||||
self.presentViewController(imagePicker, animated: true, completion: nil)
|
||||
@@ -855,7 +860,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftTextCellIdentifier, forIndexPath: indexPath) as! ChatLeftTextCell
|
||||
|
||||
cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message))
|
||||
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
@@ -881,7 +886,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightTextCellIdentifier, forIndexPath: indexPath) as! ChatRightTextCell
|
||||
|
||||
cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message))
|
||||
|
||||
|
||||
return cell
|
||||
}
|
||||
}
|
||||
@@ -1105,8 +1110,30 @@ extension ConversationViewController: AVAudioPlayerDelegate {
|
||||
|
||||
extension ConversationViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
|
||||
|
||||
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
|
||||
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
|
||||
|
||||
if let mediaType = info[UIImagePickerControllerMediaType] as? String {
|
||||
println("mediaType \(mediaType)")
|
||||
|
||||
switch mediaType {
|
||||
case kUTTypeImage as! String:
|
||||
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
|
||||
sendImage(image)
|
||||
}
|
||||
case kUTTypeMovie as! String:
|
||||
if let videoURL = info[UIImagePickerControllerMediaURL] as? NSURL {
|
||||
println("videoURL \(videoURL)")
|
||||
sendVideoWithVideoURL(videoURL)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
dismissViewControllerAnimated(true, completion: nil)
|
||||
}
|
||||
|
||||
func sendImage(image: UIImage) {
|
||||
// Prepare meta data
|
||||
|
||||
var metaData: String? = nil
|
||||
@@ -1121,11 +1148,11 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
|
||||
// Do send
|
||||
|
||||
var imageData = UIImageJPEGRepresentation(image, YepConfig.messageImageCompressionQuality())
|
||||
let imageData = UIImageJPEGRepresentation(image, YepConfig.messageImageCompressionQuality())
|
||||
|
||||
let messageImageName = NSUUID().UUIDString
|
||||
|
||||
if let withFriend = self.conversation.withFriend {
|
||||
if let withFriend = conversation.withFriend {
|
||||
|
||||
sendImageInFilePath(nil, orFileData: imageData, metaData: metaData, toRecipient: withFriend.userID, recipientType: "User", afterCreatedMessage: { message -> Void in
|
||||
|
||||
@@ -1153,7 +1180,7 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
println("sendImage to friend: \(success)")
|
||||
})
|
||||
|
||||
} else if let withGroup = self.conversation.withGroup {
|
||||
} else if let withGroup = conversation.withGroup {
|
||||
sendImageInFilePath(nil, orFileData: imageData, metaData: nil, toRecipient: withGroup.groupID, recipientType: "Circle", afterCreatedMessage: { message -> Void in
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
@@ -1167,19 +1194,93 @@ extension ConversationViewController: UIImagePickerControllerDelegate, UINavigat
|
||||
}
|
||||
realm.commitWriteTransaction()
|
||||
}
|
||||
|
||||
|
||||
self.updateConversationCollectionView()
|
||||
}
|
||||
|
||||
|
||||
}, failureHandler: {(reason, errorMessage) -> () in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
// TODO: sendImage 错误提醒
|
||||
|
||||
|
||||
}, completion: { success -> Void in
|
||||
println("sendImage to friend: \(success)")
|
||||
println("sendImage to group: \(success)")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
dismissViewControllerAnimated(true, completion: nil)
|
||||
func sendVideoWithVideoURL(videoURL: NSURL) {
|
||||
|
||||
// Prepare meta data
|
||||
|
||||
var metaData: String? = nil
|
||||
|
||||
var thumbnailData: NSData?
|
||||
|
||||
if let image = thumbnailImageOfVideoInVideoURL(videoURL) {
|
||||
let videoMetaDataInfo = ["video_width": image.size.width, "video_height": image.size.height]
|
||||
|
||||
if let videoMetaData = NSJSONSerialization.dataWithJSONObject(videoMetaDataInfo, options: nil, error: nil) {
|
||||
let videoMetaDataString = NSString(data: videoMetaData, encoding: NSUTF8StringEncoding) as? String
|
||||
metaData = videoMetaDataString
|
||||
}
|
||||
|
||||
thumbnailData = UIImageJPEGRepresentation(image, YepConfig.messageImageCompressionQuality())
|
||||
}
|
||||
|
||||
let messageVideoName = NSUUID().UUIDString
|
||||
|
||||
let afterCreatedMessageAction = { (message: Message) in
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
if let videoData = NSData(contentsOfURL: videoURL) {
|
||||
|
||||
if let messageVideoURL = NSFileManager.saveMessageImageData(videoData, withName: messageVideoName) {
|
||||
let realm = message.realm
|
||||
realm.beginWriteTransaction()
|
||||
|
||||
if let thumbnailData = thumbnailData {
|
||||
if let thumbnailURL = NSFileManager.saveMessageImageData(thumbnailData, withName: messageVideoName) {
|
||||
message.localThumbnailName = messageVideoName
|
||||
}
|
||||
}
|
||||
|
||||
message.localAttachmentName = messageVideoName
|
||||
|
||||
message.mediaType = MessageMediaType.Video.rawValue
|
||||
if let metaData = metaData {
|
||||
message.metaData = metaData
|
||||
}
|
||||
realm.commitWriteTransaction()
|
||||
}
|
||||
|
||||
self.updateConversationCollectionView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let withFriend = conversation.withFriend {
|
||||
sendVideoInFilePath(videoURL.path!, orFileData: nil, metaData: metaData, toRecipient: withFriend.userID, recipientType: "User", afterCreatedMessage: afterCreatedMessageAction, failureHandler: {(reason, errorMessage) -> () in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
// TODO: sendVideo 错误提醒
|
||||
|
||||
}, completion: { success -> Void in
|
||||
println("sendVideo to friend: \(success)")
|
||||
})
|
||||
|
||||
} else if let withGroup = conversation.withGroup {
|
||||
sendVideoInFilePath(videoURL.path!, orFileData: nil, metaData: nil, toRecipient: withGroup.groupID, recipientType: "Circle", afterCreatedMessage: afterCreatedMessageAction, failureHandler: {(reason, errorMessage) -> () in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
// TODO: sendVideo 错误提醒
|
||||
|
||||
}, completion: { success -> Void in
|
||||
println("sendVideo to group: \(success)")
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user