iOS音频与视频的开发(一)-使用AVAudioPlayer播放音乐、使用AVPlayerViewController播放视频

  iOS的多媒体支持非常强大,它提供了多套支持多媒体的API,无论是音频、视频的播放,还是录制,iOS都提供了多种API支持。借助于这些API的支持,iOS应用既可以查看、播放手机相册中的照片、视频,也可以播放来自网络的视频.iOS也提供了对摄像头、麦克风的支持。

1、使用AVAudioPlayer播放音乐

  AVAudioPlayer比较简单,当控制AVAudioPlayer对象装载音频完成后,就可以调用AVAudioPlayer的如下方法进行播放控制了。

  如:play/pause/stop/prepareToPlay.

  其中:如果调用play方法时,如果音频还没有准备好,程序会隐式先执行prepareToPlay方法。

  除此之外,AVAudioPlayer还提供了如下属性来访问音频文件的相关信息。

  playing:该属性(只读)返回播放器是否正在播放。

  pan:该属性用于设置或返回立体声平衡。如果该属性设为-1.0,则完全在左边播放;如果设为0.0则左右音量相同;如果设为1.0,则完全右边播放。

  enableRate:是否允许改边播放速率。

  numberOfLoops:设置循环次数。如果为-1标识无限循环。

  numberOfChannels:返回音频的声道数目。

  duration:音频的持续时间

  currentTime:获取音频的播放点。

  url:返回播放器关联的音频URL。

 案例代码:

import UIKit
import AVKit
class NADiscoverViewController : UIViewController {
    
    lazy var audioPlayer = AVAudioPlayer.init()
    var durationTime:Float = 0.0 //播放时长
    var timer : Timer?
    
    lazy var startBtn : UIButton = {
        let startBtn = UIButton()
        startBtn.setImage(UIImage.init(named: "bofang"), for: .normal)
        startBtn.addTarget(self, action: #selector(playAction(sender:)), for: .touchUpInside)
        return startBtn
    }()
    
    lazy var finishBtn : UIButton = {
        let finishBtn = UIButton()
        finishBtn.setImage(UIImage.init(named: "jieshu"), for: .normal)
        finishBtn.addTarget(self , action: #selector(endAction(sender:)), for:.touchUpInside)
        return finishBtn
    }()
    
    lazy var progress : UIProgressView = {
        let progress = UIProgressView()
        return progress
    }()
    
    lazy var messageLabel : UILabel = {
        let messageLabel = UILabel()
        messageLabel.text = "时长"
        messageLabel.numberOfLines = 0
        return messageLabel
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.title = "发现"
        
        setSubViewConstraints()
        let fileURL : URL = Bundle.main.url(forResource: "a", withExtension: "mp3")!
        
        do {
            let player : AVAudioPlayer = try AVAudioPlayer.init(contentsOf: fileURL)
            audioPlayer = player
        }catch{}
        let str = String.init(format: "音频文件的声道数:%d\n音频文件的持续时间:%g", audioPlayer.numberOfChannels,audioPlayer.duration)
        messageLabel.text = str
        durationTime = Float(audioPlayer.duration)
        //将循环次数设为-1,用于指定该音频文件循环播放
        audioPlayer.numberOfLoops = -1
        audioPlayer.delegate = self
    }
    
    @objc func playAction(sender:UIButton) -> Void {
        if audioPlayer.isPlaying {
            audioPlayer.pause()
            startBtn.setImage(UIImage.init(named: "bofang"), for: .normal)
        } else {
            audioPlayer.play()
            startBtn.setImage(UIImage.init(named: "zanting"), for: .normal)
        }
        if timer == nil {
            timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateProge), userInfo: nil, repeats: true)
        }
    }
    @objc func endAction(sender:UIButton) -> Void {
        audioPlayer.stop()
        timer?.isValid
        timer = nil
    }
    
    @objc func updateProge() {
        progress.progress = Float(audioPlayer.currentTime) / durationTime
    }
    func setSubViewConstraints() -> Void {
        view.addSubview(startBtn)
        startBtn.snp.makeConstraints { (make) in
            make.top.equalTo(100)
            make.left.equalTo(50)
            make.width.height.equalTo(50)
        }
        
        view.addSubview(finishBtn)
        finishBtn.snp.makeConstraints { (make) in
            make.top.equalTo(startBtn)
            make.right.equalTo(-50)
            make.width.height.equalTo(50)
        }
        
        view.addSubview(progress)
        progress.snp.makeConstraints { (make) in
            make.top.equalTo(startBtn.snp_bottom).offset(30)
            make.left.equalTo(50)
            make.right.equalTo(-50)
        }
        view.addSubview(messageLabel)
        messageLabel.snp.makeConstraints { (make) in
            make.top.equalTo(progress.snp_bottom).offset(30)
            make.left.equalTo(50)
            make.right.equalTo(-50)
        }
    }
}

extension NADiscoverViewController : AVAudioPlayerDelegate {
    //当audioplayer播放完成后将会自动播放
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        if player == audioPlayer && flag {
            print("播放完成")
            
        }
    }
    
    func audioPlayerBeginInterruption(_ player: AVAudioPlayer) {
        if player == audioPlayer {
            print("被中断了")
        }
    }
}
播放本地音乐

 效果图:

2、使用AVPlayerViewController播放视频

  支持的视频编码格式很有限:H.264、MPEG-4,扩展名(压缩格式):.mp4、.mov、.m4v、.m2v、.3gp、.3g2等,如果是RMVB就不行了,需要借助第三方的框架来实现更多格式的支持。

  使用AVPlayerViewController之前先导入AVKit头文件

  AVPlayerViewController中集成了AVPlayer,AVPlayer提供了一些方法可以轻易实现对视频播放的控制

  如:play/pause/status

  AVPlayerViewController常用属性:

  showsPlaybackControls:是否显示回放控制

  entersFullScreenWhenPlaybackBegins:开启这个播放的时候支持(全屏)横竖屏

  exitsFullScreenWhenPlaybackEnds:开启这个播放结束的时候,可以退出全屏

  案例代码:

import UIKit
import AVKit
class NAPublishViewController : UIViewController {
    var moviePlayer = AVPlayerViewController.init()
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let movieUrl : URL = Bundle.main.url(forResource: "movie", withExtension: "mp4")!
        //使用指定的url创建MPMoviesPlayerController
        moviePlayer.player = AVPlayer.init(url: movieUrl)
        //是否显示回放控制
        moviePlayer.showsPlaybackControls = true
        //开启这个播放的时候支持(全屏)横竖屏
        if #available(iOS 11.0, *) {
            moviePlayer.entersFullScreenWhenPlaybackBegins = true
        }
        //开启这个播放结束的是否,可以退出全屏
        if #available(iOS 11.0, *) {
            moviePlayer.exitsFullScreenWhenPlaybackEnds = true
        }
        view.addSubview(moviePlayer.view)
        //判断moviePlayer已经准备好视频第一播放帧
        if moviePlayer.isReadyForDisplay {
            moviePlayer.player?.play()
        }
        
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
AVPlayerViewController播放视频

  通过上面几行代码,就可以实现本地或网络视频的播放。

        

 

全部评论

相关推荐

咦哟,从去年八月份开始长跑,两处实习转正都失败了,风雨飘摇,终于拿到offer了更新一下面试记录:秋招:多部门反复面试然后挂掉然后复活,具体问了啥已经忘了,只是被反复煎炸,直至焦香😋春招:base北京抖音hr打来电话说再次复活,准备面试,gogogo北京抖音一面:六道笔试题:1.promise顺序2.定义域问题3.flat展开4.并发请求5.岛屿数量算法(力扣)深度,广度都写6.忘记了,好像也是算法,难度中等其他问题多是框架底层设计,实习项目重难点~~~秒过😇北京抖音二面:三道笔试题:(为什么只有三道是因为第三道没做出来,卡住了)1.中等难度算法(忘记啥题了,应该是个数组的)2.认识js的继承本质(手写继承模式,深入js的面相对象开发)3.手写vue的响应式(卡在了watch,导致挂掉)---后知后觉是我的注册副作用函数写得有问题,有点紧张了其他题目多是项目拷打,项目亮点,对实习项目的贡献~~~第二天,挂,but立马复活转战深圳客服当天约面深圳客服一面:六道笔试题,由于面过太多次字节,面试官叫我直接写,不用讲,快些写完😋,具体都是些继承,深拷贝(注意对数组对象分开处理,深层次对象,循环引用),加中等难度算法题~~~秒过深圳客服二面:口诉八股大战:大概囊括网络,浏览器渲染原理,动画优化,时间循环,任务队列等等(你能想到的简单八股通通拉出来鞭尸😋)算法题:笔试题6道:1:找出数组内重复的数,arr[0]-arr[n]内的数大小为[1-n],例如[1,2,2,3,3]返回[2,3],要求o(n),且不使用任何额外空间(做到了o(n),空间方面欠佳,给面试官说进入下一题,做不来了)2:原滋原味的继承(所以继承真滴很重要)3:力扣股票购买时机难度中等其他滴也忘记了,因为拿到offer后鼠鼠一下子就落地了,脑子自动过滤掉可能会攻击鼠鼠的记忆😷~~~秒过深圳客服三面:项目大战参与战斗的人员有:成员1:表单封装及其底层原理,使用成本的优化,声明式表单成员2:公司内部库生命周期管理成员3:第三方库和内部库冲突如何源码断点调试并打补丁解决成员4:埋点的艺术成员5:线上项目捷报频传如何查出内鬼成员6:大文件分片的风流趣事成员7:设计模式对对碰成员8:我构建hooks应对经理的新增的小需求的故事可能项目回答的比较流利,笔试题3道,都很简单,相信大家应该都可以手拿把掐😇~~~过过过无hr面后续煎熬等待几天直接hr打电话发offer了,希望大家也可以拿到自己心仪的offer
法力无边年:牛哇,你真是准备得充分,我对你没有嫉妒,都是实打实付出
查看19道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务