mirror of
https://github.com/wahyd4/Yep.git
synced 2026-08-20 10:16:16 +10:00
Refine Wave Compress
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
0A8F54C71AB67D11004AD60E /* YepTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8F54C61AB67D11004AD60E /* YepTests.swift */; };
|
||||
0A944C251AC8BB2F00037A06 /* YepStorageService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A944C241AC8BB2F00037A06 /* YepStorageService.swift */; };
|
||||
0AAFCFF91AC8CA5B00EB0EF8 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AAFCFF81AC8CA5B00EB0EF8 /* MobileCoreServices.framework */; };
|
||||
0ABF3EA71ACE60D5001E76ED /* Waver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABF3EA51ACE60D5001E76ED /* Waver.swift */; };
|
||||
0AD7EA5E1AC3ED1200617758 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AD7EA5D1AC3ED1200617758 /* CFNetwork.framework */; };
|
||||
0AD7EA601AC3ED1900617758 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AD7EA5F1AC3ED1900617758 /* CoreFoundation.framework */; };
|
||||
0AD7EA621AC3ED2100617758 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AD7EA611AC3ED2100617758 /* CoreTelephony.framework */; };
|
||||
@@ -87,8 +88,6 @@
|
||||
50A9D44B1ACD37A8000B2599 /* NSFileManager+Yep.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A9D44A1ACD37A8000B2599 /* NSFileManager+Yep.swift */; };
|
||||
50A9D44E1ACD382B000B2599 /* NSDateTimeAgo.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 50A9D44C1ACD382B000B2599 /* NSDateTimeAgo.bundle */; };
|
||||
50A9D4511ACD383E000B2599 /* NSDate+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A9D4501ACD383E000B2599 /* NSDate+Extension.swift */; };
|
||||
50A9D4551ACD393A000B2599 /* SquareWaveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A9D4521ACD393A000B2599 /* SquareWaveView.swift */; };
|
||||
50A9D4561ACD393A000B2599 /* Waver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A9D4531ACD393A000B2599 /* Waver.swift */; };
|
||||
50A9D4571ACD393A000B2599 /* YepWaverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A9D4541ACD393A000B2599 /* YepWaverView.swift */; };
|
||||
50CDBE421ACA9B4200459CE0 /* ChatRightImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50CDBE401ACA9B4200459CE0 /* ChatRightImageCell.swift */; };
|
||||
50CDBE431ACA9B4200459CE0 /* ChatRightImageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 50CDBE411ACA9B4200459CE0 /* ChatRightImageCell.xib */; };
|
||||
@@ -130,6 +129,7 @@
|
||||
0A8F54C61AB67D11004AD60E /* YepTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YepTests.swift; sourceTree = "<group>"; };
|
||||
0A944C241AC8BB2F00037A06 /* YepStorageService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepStorageService.swift; path = Services/YepStorageService.swift; sourceTree = "<group>"; };
|
||||
0AAFCFF81AC8CA5B00EB0EF8 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
||||
0ABF3EA51ACE60D5001E76ED /* Waver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Waver.swift; sourceTree = "<group>"; };
|
||||
0AD7EA511AC3EA6F00617758 /* JPushSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JPushSDK.framework; path = "Pods/../build/Debug-iphoneos/Pods/JPushSDK.framework"; sourceTree = "<group>"; };
|
||||
0AD7EA581AC3EAF300617758 /* Yep-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Yep-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
0AD7EA5B1AC3ECD700617758 /* libPushSDK-1.8.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPushSDK-1.8.3.a"; path = "Yep/lib/libPushSDK-1.8.3.a"; sourceTree = "<group>"; };
|
||||
@@ -201,8 +201,6 @@
|
||||
50A9D44A1ACD37A8000B2599 /* NSFileManager+Yep.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSFileManager+Yep.swift"; path = "Extensions/NSFileManager+Yep.swift"; sourceTree = "<group>"; };
|
||||
50A9D44C1ACD382B000B2599 /* NSDateTimeAgo.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = NSDateTimeAgo.bundle; path = Extensions/NSDateTimeAgo.bundle; sourceTree = "<group>"; };
|
||||
50A9D4501ACD383E000B2599 /* NSDate+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "NSDate+Extension.swift"; path = "Extensions/NSDate+Extension.swift"; sourceTree = "<group>"; };
|
||||
50A9D4521ACD393A000B2599 /* SquareWaveView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SquareWaveView.swift; path = Views/AudioWaves/SquareWaveView.swift; sourceTree = "<group>"; };
|
||||
50A9D4531ACD393A000B2599 /* Waver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Waver.swift; path = Views/AudioWaves/Waver.swift; sourceTree = "<group>"; };
|
||||
50A9D4541ACD393A000B2599 /* YepWaverView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepWaverView.swift; path = Views/AudioWaves/YepWaverView.swift; sourceTree = "<group>"; };
|
||||
50CDBE401ACA9B4200459CE0 /* ChatRightImageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ChatRightImageCell.swift; path = Views/Cells/ChatRightImage/ChatRightImageCell.swift; sourceTree = "<group>"; };
|
||||
50CDBE411ACA9B4200459CE0 /* ChatRightImageCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = ChatRightImageCell.xib; path = Views/Cells/ChatRightImage/ChatRightImageCell.xib; sourceTree = "<group>"; };
|
||||
@@ -660,9 +658,8 @@
|
||||
50A9D4581ACD3943000B2599 /* AudioWaves */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
50A9D4521ACD393A000B2599 /* SquareWaveView.swift */,
|
||||
0ABF3EA51ACE60D5001E76ED /* Waver.swift */,
|
||||
504F41241ACE2D1D00FBB19A /* SampleView.swift */,
|
||||
50A9D4531ACD393A000B2599 /* Waver.swift */,
|
||||
50A9D4541ACD393A000B2599 /* YepWaverView.swift */,
|
||||
);
|
||||
name = AudioWaves;
|
||||
@@ -922,14 +919,13 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
50CDBE421ACA9B4200459CE0 /* ChatRightImageCell.swift in Sources */,
|
||||
50A9D4561ACD393A000B2599 /* Waver.swift in Sources */,
|
||||
5099B9C41AB9510D002F940B /* RankView.swift in Sources */,
|
||||
502AE5311AB85067005BD199 /* RegisterPickMobileViewController.swift in Sources */,
|
||||
5099B9C91AB9A7CB002F940B /* CameraPreviewView.swift in Sources */,
|
||||
50A9D4551ACD393A000B2599 /* SquareWaveView.swift in Sources */,
|
||||
502AE5581AB932D5005BD199 /* ProfileSectionHeaderReusableView.swift in Sources */,
|
||||
502AE5211AB71C7E005BD199 /* BorderButton.swift in Sources */,
|
||||
502AE54E1AB93175005BD199 /* ProfileHeaderCell.swift in Sources */,
|
||||
0ABF3EA71ACE60D5001E76ED /* Waver.swift in Sources */,
|
||||
502AE5381AB866E3005BD199 /* LoginVerifyMobileViewController.swift in Sources */,
|
||||
503CAB431AC00CB100DFE830 /* ConversationViewController.swift in Sources */,
|
||||
5023DE331AB688F600B3EE96 /* UIColor+Yep.swift in Sources */,
|
||||
|
||||
@@ -15,7 +15,6 @@ class ConversationViewController: UIViewController {
|
||||
var conversation: Conversation!
|
||||
|
||||
var waverView: YepWaverView!
|
||||
var audioSamples = [Float]()
|
||||
var samplesCount = 0
|
||||
let samplingInterval = 6
|
||||
|
||||
@@ -178,10 +177,6 @@ class ConversationViewController: UIViewController {
|
||||
|
||||
var normalizedValue = pow(10, audioRecorder.averagePowerForChannel(0)/40)
|
||||
|
||||
if (++self.samplesCount % self.samplingInterval) == 0 {
|
||||
self.audioSamples.append(normalizedValue)
|
||||
}
|
||||
|
||||
self.waverView.waver.level = CGFloat(normalizedValue)
|
||||
}
|
||||
}
|
||||
@@ -206,7 +201,7 @@ class ConversationViewController: UIViewController {
|
||||
|
||||
let audioFileName = NSUUID().UUIDString
|
||||
|
||||
self.audioSamples.removeAll(keepCapacity: true)
|
||||
self.waverView.waver.resetWaveSamples()
|
||||
self.samplesCount = 0
|
||||
|
||||
if let fileURL = NSFileManager.yepMessageAudioURLWithName(audioFileName) {
|
||||
@@ -228,13 +223,15 @@ class ConversationViewController: UIViewController {
|
||||
|
||||
var metaData: String? = nil
|
||||
|
||||
let audioSamples = self.audioSamples
|
||||
let audioSamples = self.waverView.waver.compressSamples()
|
||||
|
||||
if let fileURL = YepAudioService.sharedManager.audioFileURL {
|
||||
let audioAsset = AVURLAsset(URL: fileURL, options: nil)
|
||||
let audioDuration = CMTimeGetSeconds(audioAsset.duration) as Double
|
||||
|
||||
let audioMetaDataInfo = ["audio_samples": audioSamples, "audio_duration": audioDuration]
|
||||
println("Comporessed \(audioSamples)")
|
||||
|
||||
let audioMetaDataInfo = ["audio_samples": audioSamples!, "audio_duration": audioDuration]
|
||||
|
||||
if let audioMetaData = NSJSONSerialization.dataWithJSONObject(audioMetaDataInfo, options: nil, error: nil) {
|
||||
let audioMetaDataString = NSString(data: audioMetaData, encoding: NSUTF8StringEncoding) as? String
|
||||
@@ -669,6 +666,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
if let metaDataDict = decodeJSON(data) {
|
||||
|
||||
if let audioSamples = metaDataDict["audio_samples"] as? [CGFloat] {
|
||||
//
|
||||
cell.sampleViewWidthConstraint.constant = CGFloat(audioSamples.count) * (YepConfig.audioSampleWidth() + YepConfig.audioSampleGap()) - YepConfig.audioSampleGap() // 最后最后一个 gap 不要
|
||||
cell.sampleView.samples = audioSamples
|
||||
|
||||
|
||||
@@ -55,8 +55,11 @@ class SampleView: UIView {
|
||||
for (index, percent) in enumerate(samples) {
|
||||
|
||||
let x = CGFloat(index) * sampleWidth + sampleGap * CGFloat(index)
|
||||
let sampleHeightMax = viewHeight * 0.8
|
||||
let realSampleHeight = percent * viewHeight
|
||||
|
||||
|
||||
let sampleHeight = percent * (viewHeight * 0.9)
|
||||
let sampleHeight = realSampleHeight < sampleHeightMax ? realSampleHeight: sampleHeightMax
|
||||
|
||||
wavePath.moveToPoint(CGPointMake(x, viewHeight / 2.0 - sampleHeight / 2.0))
|
||||
wavePath.addLineToPoint(CGPointMake(x, sampleHeight / 2.0 + viewHeight / 2.0))
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
//
|
||||
// SquareWaveView.swift
|
||||
// Waver-Swift
|
||||
//
|
||||
// Created by kevinzhow on 15/4/1.
|
||||
// Copyright (c) 2015年 kevinzhow. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SquareWaveView: UIView {
|
||||
|
||||
var maxHeight: CGFloat = 1.0
|
||||
|
||||
var waves = [CGFloat]()
|
||||
|
||||
var wave = CAShapeLayer()
|
||||
|
||||
var waveWidth: CGFloat = 4.0
|
||||
|
||||
var waveGap: CGFloat = 1.0
|
||||
|
||||
var waveTotalCount: CGFloat!
|
||||
|
||||
var waveSampleCount = 0
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
override func drawRect(rect: CGRect) {
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
required init(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
setup()
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setup()
|
||||
}
|
||||
|
||||
func setup() {
|
||||
|
||||
wave.lineCap = kCALineCapButt
|
||||
wave.lineJoin = kCALineJoinRound
|
||||
wave.fillColor = UIColor.clearColor().CGColor
|
||||
wave.lineWidth = waveWidth
|
||||
wave.strokeColor = UIColor.grayColor().CGColor
|
||||
self.layer.addSublayer(wave)
|
||||
|
||||
waveTotalCount = self.bounds.width/(waveWidth+waveGap)
|
||||
|
||||
}
|
||||
|
||||
private func updateMeters() {
|
||||
UIGraphicsBeginImageContext(self.frame.size)
|
||||
|
||||
var wavesPath = UIBezierPath()
|
||||
|
||||
for (index, wave) in enumerate(waves) {
|
||||
|
||||
var x = CGFloat(index) * waveWidth + waveGap * CGFloat(index)
|
||||
|
||||
wavesPath.moveToPoint(CGPointMake(x, self.bounds.height/2.0 - wave/2.0))
|
||||
wavesPath.addLineToPoint(CGPointMake(x, wave/2.0 + self.bounds.height/2.0))
|
||||
|
||||
}
|
||||
|
||||
wave.path = wavesPath.CGPath
|
||||
|
||||
UIGraphicsEndImageContext()
|
||||
}
|
||||
|
||||
func appendValue(newValue: CGFloat) {
|
||||
|
||||
if ++waveSampleCount % 6 == 0{
|
||||
|
||||
waves.append(newValue*self.bounds.height)
|
||||
|
||||
if waves.count > Int(waveTotalCount) {
|
||||
waves.removeAtIndex(0)
|
||||
}
|
||||
|
||||
updateMeters()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,9 @@ class Waver: UIView {
|
||||
didSet {
|
||||
self.phase+=self.phaseShift; // Move the wave
|
||||
self.amplitude = fmax( level, self.idleAmplitude)
|
||||
|
||||
self.appendValue(pow(CGFloat(level),3))
|
||||
|
||||
self.updateMeters()
|
||||
}
|
||||
}
|
||||
@@ -42,10 +45,30 @@ class Waver: UIView {
|
||||
|
||||
//
|
||||
|
||||
private var waveHeight: CGFloat!
|
||||
private var waveWidth: CGFloat!
|
||||
private var waveMid: CGFloat!
|
||||
private var maxAmplitude: CGFloat!
|
||||
var waveHeight: CGFloat!
|
||||
var waveWidth: CGFloat!
|
||||
var waveMid: CGFloat!
|
||||
var maxAmplitude: CGFloat!
|
||||
|
||||
// Sample Data
|
||||
|
||||
var waveSampleCount = 0
|
||||
|
||||
var waveSamples = [CGFloat]()
|
||||
|
||||
var waveTotalCount: CGFloat!
|
||||
|
||||
var waveSquareWidth: CGFloat = 2.0
|
||||
|
||||
var waveGap: CGFloat = 1.0
|
||||
|
||||
var maxSquareWaveLength = 256
|
||||
|
||||
var maxTime = 60
|
||||
|
||||
var fps = 6
|
||||
|
||||
//
|
||||
|
||||
var waverCallback: (() -> ())? {
|
||||
didSet {
|
||||
@@ -84,6 +107,16 @@ class Waver: UIView {
|
||||
setup()
|
||||
}
|
||||
|
||||
func appendValue(newValue: CGFloat) {
|
||||
|
||||
if ++waveSampleCount % fps == 0{
|
||||
|
||||
waveSamples.append(newValue*5)
|
||||
|
||||
updateMeters()
|
||||
}
|
||||
}
|
||||
|
||||
private func setup() {
|
||||
|
||||
self.waveHeight = CGRectGetHeight(self.bounds) * 0.9
|
||||
@@ -137,6 +170,68 @@ class Waver: UIView {
|
||||
UIGraphicsEndImageContext()
|
||||
}
|
||||
|
||||
func compressSamples() -> [Float]? {
|
||||
|
||||
println("Begin compress")
|
||||
|
||||
var finalSamples = [Float]()
|
||||
|
||||
var samplesCount = waveSamples.count //获取总的 Sample 数量
|
||||
|
||||
var totalTime:CGFloat = CGFloat(waveSamples.count/(60/fps)) // 计算音频的时长
|
||||
|
||||
var bubbleWidth = -0.071*(totalTime*totalTime) + 8.532*totalTime //计算这个时长下的Bubble宽度,Bubble 的宽度和时间的关系函数是一个一元二次函数
|
||||
|
||||
var effectiveSample = bubbleWidth/(waveSquareWidth+waveGap) < 1 ? 1 : bubbleWidth/(waveSquareWidth+waveGap) //计算这个长度里实际可以放多少个sample图形
|
||||
if (effectiveSample > 10) {
|
||||
|
||||
}
|
||||
|
||||
var sampleGap = Int(CGFloat(samplesCount)/effectiveSample) //计算按照实际可放的sample数量,原sample需要每几个合并一次
|
||||
|
||||
var timePerSample = totalTime/(CGFloat(samplesCount)/effectiveSample) //计算合并后每个 sample 需要经过多少时间播放
|
||||
|
||||
|
||||
|
||||
println("samplesCount \(samplesCount) totalTime \(totalTime) bubbleWidth \(bubbleWidth) effectiveSample\(effectiveSample) sampleGap \(sampleGap) timePerSample\(timePerSample)")
|
||||
|
||||
//
|
||||
|
||||
var sampleCount = 0
|
||||
|
||||
var lastSample: CGFloat = 0
|
||||
|
||||
for sample in waveSamples {
|
||||
|
||||
if ++sampleCount > sampleGap {
|
||||
sampleCount = 0
|
||||
finalSamples.append(Float(lastSample))
|
||||
lastSample = 0
|
||||
}else{
|
||||
if (sample > lastSample) {
|
||||
lastSample = sample
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (finalSamples.count < 10){
|
||||
|
||||
finalSamples = [Float]()
|
||||
|
||||
for sample in waveSamples {
|
||||
finalSamples.append(Float(sample))
|
||||
}
|
||||
}
|
||||
|
||||
println("Final Sample is \(finalSamples)")
|
||||
|
||||
return finalSamples
|
||||
}
|
||||
|
||||
func resetWaveSamples() {
|
||||
waveSamples = [CGFloat]()
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
Reference in New Issue
Block a user