質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1732閲覧

swift3 MPMusicPlayerControllerで再生時間を表示

mitci

総合スコア37

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/08/14 11:35

編集2017/08/18 11:50

###前提・実現したいこと
MediaPlayerフレームワークをインポートして
再生中の曲の情報を表示するだけのアプリを作りました。

曲のタイトルやアーティスト名などは簡単に表示することができたのですが、
現在の再生時間を画面に表示することが全くできません。


2017.8.17更新
timerとcurrentPlaybackTimeを使って
timerで1秒ごとにUILabelを書き換える動作にしようと思いました。

swift

1 var timer = Timer() 2 var count: Double = 0.0 3 var countInt: Int = 0 4 @IBOutlet weak var timeCounter: UILabel! 5@IBOutlet 6 //〜省略〜 7 func nowPlayingItemChanged(_ notification: NSNotification?) { 8 if let mediaItem = player.nowPlayingItem { 9 updateSongInformationUI(mediaItem: mediaItem) 10 } 11 } 12 13 func updateSongInformationUI(mediaItem: MPMediaItem) { 14 //〜省略〜 15 timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateElapsedTime), userInfo: nil, repeats: true) 16} 17 18 func updateElapsedTime() { 19 count = player.currentPlaybackTime 20 countInt = Int(count) 21 let min = countInt / 60 22 let sec = countInt % 60 23 timeCounter.text = String(format:"%02d:%02d",min, sec) 24//ここでTimeInterval型->Int型->String型に変更してやっとUILabelに代入する 25 }

曲が変更された時、それが再生可能な曲であれば、タイマーをスタートさせるという設定にしたつもりです。
そして、TimeInterval型であるcurrentPlaybackTimeを小数点は切り捨ててInt型にし(そうしないと % 60 が使えなかったため)、最後にUIlabelのtimePathにmm:ssのフォーマットのString型として代入したつもりです。

###現在発生しているエラー
ビルドタイムエラーはなく、実機で起動した際に

swift

1testMusic`ViewController.init(coder : NSCoder) -> ViewController?: 2 0x1000e760c <+0>: sub sp, sp, #0xc0 ; =0xc0 3 0x1000e7610 <+4>: stp x29, x30, [sp, #0xb0] 4 0x1000e7614 <+8>: add x29, sp, #0xb0 ; =0xb0 5 0x1000e7618 <+12>: adrp x8, 6 6 0x1000e761c <+16>: add x8, x8, #0xee8 ; =0xee8 7 0x1000e7620 <+20>: stur x0, [x29, #-0x10] 8 0x1000e7624 <+24>: stur x1, [x29, #-0x8] 9 0x1000e7628 <+28>: stur xzr, [x29, #-0x18] 10 0x1000e762c <+32>: ldur x9, [x29, #-0x18] 11-> 0x1000e7630 <+36>: ldr x8, [x8] //thread 1: breakpoint2.4 12//ここで止まってしまう・・・ 13 0x1000e7634 <+40>: mov x10, x1 14 0x1000e7638 <+44>: add x8, x10, x8 15 0x1000e763c <+48>: stur x0, [x29, #-0x50] 16 0x1000e7640 <+52>: mov x0, x8 17 0x1000e7644 <+56>: str x1, [sp, #0x58] 18 0x1000e7648 <+60>: mov x1, x9 19 0x1000e764c <+64>: str x9, [sp, #0x50] 20 0x1000e7650 <+68>: bl 0x1000e968c ; symbol stub for: swift_unknownWeakInit 21 0x1000e7654 <+72>: ldr x0, [sp, #0x50] 22 0x1000e7658 <+76>: bl 0x1000e9608 ; symbol stub for: objc_release 23 0x1000e765c <+80>: adrp x8, 6 24 0x1000e7660 <+84>: add x8, x8, #0xef0 ; =0xef0 25 0x1000e7664 <+88>: stur xzr, [x29, #-0x20] 26 0x1000e7668 <+92>: ldur x9, [x29, #-0x20] 27 0x1000e766c <+96>: ldr x8, [x8] 28 0x1000e7670 <+100>: ldr x10, [sp, #0x58] 29 0x1000e7674 <+104>: add x8, x10, x8 30 0x1000e7678 <+108>: mov x0, x8 31 0x1000e767c <+112>: mov x1, x9 32 0x1000e7680 <+116>: str x9, [sp, #0x48] 33 0x1000e7684 <+120>: bl 0x1000e968c ; symbol stub for: swift_unknownWeakInit 34 0x1000e7688 <+124>: ldr x0, [sp, #0x48] 35 0x1000e768c <+128>: bl 0x1000e9608 ; symbol stub for: objc_release 36 0x1000e7690 <+132>: adrp x8, 6 37 0x1000e7694 <+136>: add x8, x8, #0xef8 ; =0xef8 38 0x1000e7698 <+140>: stur xzr, [x29, #-0x28] 39 0x1000e769c <+144>: ldur x9, [x29, #-0x28] 40 0x1000e76a0 <+148>: ldr x8, [x8] 41 0x1000e76a4 <+152>: ldr x10, [sp, #0x58] 42 0x1000e76a8 <+156>: add x8, x10, x8 43 0x1000e76ac <+160>: mov x0, x8 44 0x1000e76b0 <+164>: mov x1, x9 45 0x1000e76b4 <+168>: str x9, [sp, #0x40] 46 0x1000e76b8 <+172>: bl 0x1000e968c ; symbol stub for: swift_unknownWeakInit 47 0x1000e76bc <+176>: ldr x0, [sp, #0x40] 48 0x1000e76c0 <+180>: bl 0x1000e9608 ; symbol stub for: objc_release 49 0x1000e76c4 <+184>: adrp x8, 6 50 0x1000e76c8 <+188>: add x8, x8, #0xf00 ; =0xf00 51 0x1000e76cc <+192>: stur xzr, [x29, #-0x30] 52 0x1000e76d0 <+196>: ldur x9, [x29, #-0x30] 53 0x1000e76d4 <+200>: ldr x8, [x8] 54 0x1000e76d8 <+204>: ldr x10, [sp, #0x58] 55 0x1000e76dc <+208>: add x8, x10, x8 56 0x1000e76e0 <+212>: mov x0, x8 57 0x1000e76e4 <+216>: mov x1, x9 58 0x1000e76e8 <+220>: str x9, [sp, #0x38] 59 0x1000e76ec <+224>: bl 0x1000e968c ; symbol stub for: swift_unknownWeakInit 60 0x1000e76f0 <+228>: ldr x0, [sp, #0x38] 61 0x1000e76f4 <+232>: bl 0x1000e9608 ; symbol stub for: objc_release 62 0x1000e76f8 <+236>: adrp x8, 6 63 0x1000e76fc <+240>: add x8, x8, #0xf08 ; =0xf08 64 0x1000e7700 <+244>: stur xzr, [x29, #-0x38] 65 0x1000e7704 <+248>: ldur x9, [x29, #-0x38] 66 0x1000e7708 <+252>: ldr x8, [x8] 67 0x1000e770c <+256>: ldr x10, [sp, #0x58] 68 0x1000e7710 <+260>: add x8, x10, x8 69 0x1000e7714 <+264>: mov x0, x8 70 0x1000e7718 <+268>: mov x1, x9 71 0x1000e771c <+272>: str x9, [sp, #0x30] 72 0x1000e7720 <+276>: bl 0x1000e968c ; symbol stub for: swift_unknownWeakInit 73 0x1000e7724 <+280>: ldr x0, [sp, #0x30] 74 0x1000e7728 <+284>: bl 0x1000e9608 ; symbol stub for: objc_release 75 0x1000e772c <+288>: bl 0x1000e3e98 ; type metadata accessor for __ObjC.MPMusicPlayerController at ViewController.swift 76 //〜省略〜

###自分なりの考察
timerを起動するタイミングがいけないのだろうか・・・。


2017.8.18再々更新
全く別のアプローチとして、currentPlaybackStateがplayingのときのみ、単純なカウンター

swift

1 func updateElapsedTime() { 2 count += 1 3 let min = count / 60 4 let sec = count % 60 5 timeCounter.text = String(format:"%02d:%02d",min, sec)

を作ってもいいのですが、そうなると、currentPlaybackStateの設定がわからず・・・
while player.PlaybackState == .playing {
ではなぜかだめらしく・・・

###補足情報(言語/FW/ツール等のバージョンなど)
swift3Xcode8

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Stripe

2017/08/15 17:07

currentPlaybackTimeプロパティは、もう確認しましたか?
mitci

2017/08/16 11:06 編集

player.currentPlaybackTimeで取得できそうなことを確認しましたが、TimeInterval型がよくわからず今頑張って調べております・・・ が、UILabelに1秒ごとに更新される"mm:ss"を表示させるやり方が全くわからず・・・
Stripe

2017/08/17 13:38

ビルド結果をクリアしてからの再ビルドは試しましたか?
mitci

2017/08/18 11:20 編集

何度もすいません。ビルド結果のクリアというのはProduct > Clean でいいのでしょうか? また、updateSongInformationUIにtimerを入れてしまうと、 曲を変更するたびになんども重複してupdateElapsedTime()が実行されてしまう気もしたので viewDidLoad()にtimerを入れてみたのですが、 全く同じエラーがでました。 ということはつまり、timerの問題ではなく、やはりCurrentPlaybackTimeをInt型にするあたりで エラーが生じているのでしょうか・・・?
mitci

2017/08/18 11:31

度々すいません。count = player.currentPlaybackTimeというのは合っていますよね・・・? ちなみに、playerは一度class UIViewController内にvar player = MPMusicPlayerController()と宣言し、viewDidLoad()内でplayerにMPMusicPlayerController.systemMusicPlayer()を代入しています
guest

回答1

0

自己解決

まったくもって自己解決ではなく、Stripeさんのおかげなのですが・・・

ランタイムエラーについてはその後調べた結果、timerに関する記述などすべてを削除しても起こってしまったため、どうやらやはりうまくビルド結果をクリアにできていなかったようです。本当にすいません。

解決法ですが、プロジェクトファイル自体を新しく作り直し、timerをviewDidLoad内に置き、起動した瞬間常に、updateElapsedTime()が実行されるようにすることで問題なくカウンターの表示が再生時間と同期するようになりました。
updateElapsedTime()は以下のようにしました。

swift

1 func updateElapsedTime() { 2 if player.nowPlayingItem != nil { 3 timeLabel.text = String(player.currentPlaybackTime) 4 } 5 }

まだmm:ssのフォーマットではありませんが、完全に同期しています。


また、Thread1 breakpoint2.4のエラーですが、
どうやらnowPlayingItemChangedメソッドにtimerを入れてしまったために、
曲が変わるたびに何度もtimerが設定されてしまい、currentPlaybackTimeの値が無限に加算されてしまっていたようで、その値を代入したcountやcountIntプロパティを削除していなかったことでずっと数値が膨大になっており、アプリの起動すらままならなくなってしまったようです。

そのために、何を試してもエラーとなってしまい、
playbackStateを利用してもcurrentPlaybackTimeを利用しても、
どちらも記述しなくても何をしてもエラーになっていました。

コードは間違ったら消せばいい、と思っていた自分の無知が話をややこしくさせていたようです。
大変申し訳ありませんでした。

投稿2017/08/18 13:20

mitci

総合スコア37

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問