音楽プレイヤの作成
2010. 07. 21
『基礎からのiPhone SDK 改訂版』も今回の『iPodライブラリアクセス+音楽プレイヤ』が最後のお題となります。
●音楽プレイヤの概要
表題の通りMedia Playerフレームワークを使ってiPodライブラリにアクセスし、自身のアプリケーションから楽曲を再生するものです。
画面構成は下図のようなインターフェイスになっています。
背景は(スライドショーのBGMとしての利用を前提としていますが)ただの画像です。
画面下方にあるパネルは、再生中の曲名、アルバム名、アーティスト名をラベルで表示し、『前の曲へ戻る』『再生/一時停止』『次の曲へ進む』ボタンで再生曲を制御します。
『More』と『Back』ボタンでパネルが回転して切り替えるようになっており、裏面にはアートワークを表示します。
●プロジェクトの作成
Window-based Applicationテンプレートでプロジェクト名を『MusicPlayer』とします。
●nibファイルの編集
1)画像素材の準備
編集の前に使用する素材を集めます。
背景画像はBackground.png(320x480ピクセル)を使っています)
それと出版社のサイトにあるサンプルコード(iPhoneBG2/SampleCode/MusicPlayer.01 iPodControl)から素材をお借りしてきます。
※背景画像を用意するのが面倒な場合は、サンプルコードの『photo1.jpg』を使用してください。
素材画像をプロジェクトの『MusicPlayer』フォルダにコピーし、XcodeのResourcesフォルダに使用する画像を登録します。
2)背景画像の設定
MainWindow.xibをダブルクリックしてInterface Builderを開きます。
LibraryウィンドウからImage Viewをドラッグ&ドロップでViewウィンドウに配置し、InspectorウィンドウのAttributesタブのImageでBackground.pngまたは背景用の画像を選択します。
3)制御パネルの設置
ウィンドウの下方に制御パネルを設置します。
LibraryウィンドウからImage Viewをドラッグ&ドロップでViewウィンドウに配置し、InspectorウィンドウのSizeタブでX:30、Y:290、W:260、H:180に設定します。
XとYに関しては背景画像に合わせて調整してください。本書ではW:280、H:160となっていますが、ここでは素材のbg.pngのサイズに合わせてW:260、H:180としています。
Attributesタブの『Image View』の『Image』で制御パネルの背景画像をbg.pngにします。
続いてUIImageViewの背景画像を消去するため、『View』の『Background』で『Colors』ウィンドウでOpacityを0%にします。
それと『Drawing』のOpaqueのチェックを外し、透明化を有効にします。
『Clear Context Before Drawing(前の描画内容をクリアしてから再描画する)』のチェックは今回の場合どちらでも構いません。
制御パネルへの操作を受け付けられるように、『Interaction』の『User Interaction Enable(ユーザ操作を有効にする)』にチェックを入れます。
メインウィンドウのレイアウトはこれで完了です。
4)制御パネルのレイアウト
実際の制御パネルには表と裏があり、メインウィンドウ上に貼り付けるのではなく、別のビューでレイアウトを組んでプログラム上で貼り付ける手法になっています。
まずLibraryウィンドウからViewをドラッグ&ドロップでDocumentウィンドウに2つ加え、Viewの名前をクリックし、識別のため『View Main Side』と『View More Side』に変更します。
それぞれをダブルクリックして開き、InspectorウィンドウのSizeタブでW:260、H:180に設定します。
まずMain Sideのレイアウトを行います。
View Main SideのViewウィンドウに、LibraryウィンドウからLabelを3つ、Round Rect Buttonを4つドラッグ&ドロップで配置します。
(ここでの位置やサイズはおおよそで構いません)
作業を円滑に進めるため、先に識別名を入力します。
ラベルは、InspectorウィンドウのAttributesタブで『Label』の『Text』を上から順に『Song Name』『Album Name』『Artist Name』とします。
再生制御のボタン3つに関しては、InspectorウィンドウのAttributesタブで『Button』の『Type』を『Custom』とし、Documentウィンドウで『Custom Button』となる名前をクリックして左から順に『Custom Button (Prev)』『Custom Button (Play)』『Custom Button (Next)』とします。
(Attributesタブの『Button』の『Title』で設定するとボタンの表示に反映されてしまうので、Documentウィンドウで名前の変更をしています)
裏面にするボタンはRound Rect Buttonのまま、InspectorウィンドウのAttributesタブで『Button』の『Title』を『More』とします。
次に位置とサイズをInspectorウィンドウのSizeタブで下表のように設定します。
続いてAttributesタブでの設定を行います。
まずビューの背景を透明化するため、DocumentウィンドウでView Main Sideを選択し、『View』の『Background』を『Clear Color』にし、『Drawing』の『Opaque』のチェックを外します。
ラベルは3つとも『Label』の『Layout』で『Alignment』を中央に、『View』の『Mode』を『Scale To Fill』にします。
『Label』の『Font』は、Song Nameは『Helvetica Bold, 17.0』に、Album NameとArtist Nameは『Helvetica, 14.0』に設定します。
再生制御のボタンは、『Button』の『Background』を3つとも『bgButton.png』にし、『Image』はそれぞれ左から『prev.png』『play.png』『next.png』と設定します。
裏面にするボタンは既に『Title』の設定も済んでいるので、そのままです。
Main Sideのレイアウトはこれで完了です。
続いて裏面になるMore Sideのレイアウトをします。
View Main Sideと同様にビューの背景を透明化するため、DocumentウィンドウでView More Sideを選択し、『View』の『Background』を『Clear Color』にし、『Drawing』の『Opaque』のチェックを外します。
View More SideのViewウィンドウに、LibraryウィンドウからImage Viewを1つ、Round Rect Buttonを1つドラッグ&ドロップで配置します。
(ここでの位置やサイズはおおよそで構いません)
InspectorウィンドウのSizeタブで、Image ViewはX:15、Y:15、W:150、H:150に、Round Rect Buttonは(表面のMoreボタンと同じ)X:180、Y:147、W:72、H:24に設定します。
続いてAttributesタブでの設定を行います。
Image Viewは『Image View』の『Image』を『noimage.png』に、『View』の『Drawing』の『Opaque』はアートワークを透明化しないのでチェックを入れたままに、『Interaction』の『User Interaction Enabled』は今回何も仕掛けをしないのですが後々のことを考えて一応チェックを入れています。
Round Rect Buttonは、『Button』の『Title』を『Back』にするだけです。
More Sideのレイアウトはこれで完了です。
この時点でのDocumentウィンドウの構成は下図のようになります。
●PanelControllerクラスの作成
Xcodeの『グループとファイル』ペインの『Classes』を右クリックして、コンテキストメニューから『追加』→『新規ファイル』を選択し、NSObjectのサブクラスとしてPanelControllerクラスを追加します。
●アウトレットとアクションの定義
生成したPanelControllerクラスのヘッダファイルPanelController.hに、アウトレットとアクションを定義します。
(太字が追加した部分)
●フレームワークの追加
iPodライブラリを利用するためMediaPlayerフレームワークを追加します。
Xcodeの『グループとファイル』ペインの『Frameworks』を右クリックして、コンテキストメニューから『追加』→『既存のフレームワーク』を選択し、MediaPlayer.frameworkを追加します。
●アウトレットとアクションの接続
Xcodeでの変更を保存し、Interface Builderでアウトレットとアクションの接続を行います。
まずPanelControllerクラスのインスタンスを追加するため、LibraryウィンドウからObjectをDocumentウィンドウにドラッグ&ドロップします。
Documentウィンドウの追加したObjectを選択した状態で、InspectorウィンドウのIdentityタブを開き、『Class Identity』の『Class』を『Panel Controller』にします。
InspectorウィンドウのConnectionsタブを開き、アウトレットとアクションを接続します。
ボタン類のアクションは全て『Touch Up Inside』に設定します。
●アクションメソッドの実装
PanelController.mソースファイルにメソッドを実装します。
(太字が追加した部分)
本書の説明の順序ですと、awakeFromNibメソッド内で呼び出すupdateViewメソッドの記述が後になってビルド時にエラーになりますので、updateViewメソッドはawakeFromNibメソッドの前に記述してください。
●ビルドと実行
本書内でも解説されているように、iPhone本体のiPodアプリケーションで再生曲が選択されていない場合(音楽ではなくビデオを再生した後など)では音楽が再生されず、アートワークも含めて楽曲情報も表示されません。
アートワークは楽曲にアートワークが指定されていない場合に『noimage.png』が表示されるので、楽曲が指定されていない場合は何も表示されません。
再生制御の3つのボタンも機能せず、動作が確認できるのは制御パネルを切り替える『More』と『Back』ボタンのみです。
この場合、iPodアプリケーションで一度音楽を再生してから再度MusicPlayerアプリケーションを立ち上げると、起動と同時に選択されている音楽が再生されます。
参考文献
●音楽プレイヤの概要
表題の通りMedia Playerフレームワークを使ってiPodライブラリにアクセスし、自身のアプリケーションから楽曲を再生するものです。
画面構成は下図のようなインターフェイスになっています。
背景は(スライドショーのBGMとしての利用を前提としていますが)ただの画像です。
画面下方にあるパネルは、再生中の曲名、アルバム名、アーティスト名をラベルで表示し、『前の曲へ戻る』『再生/一時停止』『次の曲へ進む』ボタンで再生曲を制御します。
『More』と『Back』ボタンでパネルが回転して切り替えるようになっており、裏面にはアートワークを表示します。
●プロジェクトの作成
Window-based Applicationテンプレートでプロジェクト名を『MusicPlayer』とします。
●nibファイルの編集
1)画像素材の準備
編集の前に使用する素材を集めます。
背景画像はBackground.png(320x480ピクセル)を使っています)
それと出版社のサイトにあるサンプルコード(iPhoneBG2/SampleCode/MusicPlayer.01 iPodControl)から素材をお借りしてきます。
bg.png | 制御パネルの背景画像 | 260 x 180 |
bgButton.png | ボタンの背景画像 | 70 x 37 |
next.png | 『次の曲へ進む』ボタンの画像 | 36 x 24 |
noimage.png | アートワーク画像が無い場合のデフォルト画像 | 150 x 150 |
play.png | 『再生/一時停止』ボタンの画像 | 36 x 24 |
prev.png | 『前の曲へ戻る』ボタンの画像 | 36 x 24 |
※背景画像を用意するのが面倒な場合は、サンプルコードの『photo1.jpg』を使用してください。
素材画像をプロジェクトの『MusicPlayer』フォルダにコピーし、XcodeのResourcesフォルダに使用する画像を登録します。
2)背景画像の設定
MainWindow.xibをダブルクリックしてInterface Builderを開きます。
LibraryウィンドウからImage Viewをドラッグ&ドロップでViewウィンドウに配置し、InspectorウィンドウのAttributesタブのImageでBackground.pngまたは背景用の画像を選択します。
3)制御パネルの設置
ウィンドウの下方に制御パネルを設置します。
LibraryウィンドウからImage Viewをドラッグ&ドロップでViewウィンドウに配置し、InspectorウィンドウのSizeタブでX:30、Y:290、W:260、H:180に設定します。
XとYに関しては背景画像に合わせて調整してください。本書ではW:280、H:160となっていますが、ここでは素材のbg.pngのサイズに合わせてW:260、H:180としています。
Attributesタブの『Image View』の『Image』で制御パネルの背景画像をbg.pngにします。
続いてUIImageViewの背景画像を消去するため、『View』の『Background』で『Colors』ウィンドウでOpacityを0%にします。
それと『Drawing』のOpaqueのチェックを外し、透明化を有効にします。
『Clear Context Before Drawing(前の描画内容をクリアしてから再描画する)』のチェックは今回の場合どちらでも構いません。
制御パネルへの操作を受け付けられるように、『Interaction』の『User Interaction Enable(ユーザ操作を有効にする)』にチェックを入れます。
メインウィンドウのレイアウトはこれで完了です。
4)制御パネルのレイアウト
実際の制御パネルには表と裏があり、メインウィンドウ上に貼り付けるのではなく、別のビューでレイアウトを組んでプログラム上で貼り付ける手法になっています。
まずLibraryウィンドウからViewをドラッグ&ドロップでDocumentウィンドウに2つ加え、Viewの名前をクリックし、識別のため『View Main Side』と『View More Side』に変更します。
それぞれをダブルクリックして開き、InspectorウィンドウのSizeタブでW:260、H:180に設定します。
まずMain Sideのレイアウトを行います。
View Main SideのViewウィンドウに、LibraryウィンドウからLabelを3つ、Round Rect Buttonを4つドラッグ&ドロップで配置します。
(ここでの位置やサイズはおおよそで構いません)
作業を円滑に進めるため、先に識別名を入力します。
ラベルは、InspectorウィンドウのAttributesタブで『Label』の『Text』を上から順に『Song Name』『Album Name』『Artist Name』とします。
再生制御のボタン3つに関しては、InspectorウィンドウのAttributesタブで『Button』の『Type』を『Custom』とし、Documentウィンドウで『Custom Button』となる名前をクリックして左から順に『Custom Button (Prev)』『Custom Button (Play)』『Custom Button (Next)』とします。
(Attributesタブの『Button』の『Title』で設定するとボタンの表示に反映されてしまうので、Documentウィンドウで名前の変更をしています)
裏面にするボタンはRound Rect Buttonのまま、InspectorウィンドウのAttributesタブで『Button』の『Title』を『More』とします。
次に位置とサイズをInspectorウィンドウのSizeタブで下表のように設定します。
Name | X | Y | W | H |
Label (Song Name) | 5 | 13 | 250 | 23 |
Label (Album Name) | 5 | 39 | 250 | 21 |
Label (Artist Name) | 5 | 64 | 250 | 23 |
Custom Button (Prev) | 11 | 99 | 70 | 37 |
Custom Button (Play) | 95 | 99 | 70 | 37 |
Custom Button (Next) | 180 | 99 | 70 | 37 |
Round Rect Button (More) | 180 | 147 | 72 | 24 |
続いてAttributesタブでの設定を行います。
まずビューの背景を透明化するため、DocumentウィンドウでView Main Sideを選択し、『View』の『Background』を『Clear Color』にし、『Drawing』の『Opaque』のチェックを外します。
ラベルは3つとも『Label』の『Layout』で『Alignment』を中央に、『View』の『Mode』を『Scale To Fill』にします。
『Label』の『Font』は、Song Nameは『Helvetica Bold, 17.0』に、Album NameとArtist Nameは『Helvetica, 14.0』に設定します。
再生制御のボタンは、『Button』の『Background』を3つとも『bgButton.png』にし、『Image』はそれぞれ左から『prev.png』『play.png』『next.png』と設定します。
裏面にするボタンは既に『Title』の設定も済んでいるので、そのままです。
Main Sideのレイアウトはこれで完了です。
続いて裏面になるMore Sideのレイアウトをします。
View Main Sideと同様にビューの背景を透明化するため、DocumentウィンドウでView More Sideを選択し、『View』の『Background』を『Clear Color』にし、『Drawing』の『Opaque』のチェックを外します。
View More SideのViewウィンドウに、LibraryウィンドウからImage Viewを1つ、Round Rect Buttonを1つドラッグ&ドロップで配置します。
(ここでの位置やサイズはおおよそで構いません)
InspectorウィンドウのSizeタブで、Image ViewはX:15、Y:15、W:150、H:150に、Round Rect Buttonは(表面のMoreボタンと同じ)X:180、Y:147、W:72、H:24に設定します。
続いてAttributesタブでの設定を行います。
Image Viewは『Image View』の『Image』を『noimage.png』に、『View』の『Drawing』の『Opaque』はアートワークを透明化しないのでチェックを入れたままに、『Interaction』の『User Interaction Enabled』は今回何も仕掛けをしないのですが後々のことを考えて一応チェックを入れています。
Round Rect Buttonは、『Button』の『Title』を『Back』にするだけです。
More Sideのレイアウトはこれで完了です。
この時点でのDocumentウィンドウの構成は下図のようになります。
●PanelControllerクラスの作成
Xcodeの『グループとファイル』ペインの『Classes』を右クリックして、コンテキストメニューから『追加』→『新規ファイル』を選択し、NSObjectのサブクラスとしてPanelControllerクラスを追加します。
●アウトレットとアクションの定義
生成したPanelControllerクラスのヘッダファイルPanelController.hに、アウトレットとアクションを定義します。
(太字が追加した部分)
#import <Foundation/Foundation.h>
#import <MediaPlayer/MediaPlayer.h> // MediaPlayerフレームワークを使用
@interface PanelController : NSObject {
MPMusicPlayerController *player; // 音楽制御用プレイヤ
// 制御パネルの表側
IBOutlet UIView *viewMainSide; // 表側の下地
IBOutlet UILabel *labelSongTitle; // 曲名表示
IBOutlet UILabel *labelAlbumTitle; // アルバム名表示
IBOutlet UILabel *labelArtist; // アーティスト名表示
// 制御パネルの裏側
IBOutlet UIView *viewMoreSide; // 裏側の下地
IBOutlet UIImageView *imageArtWork; // アートワーク表示
// その他
IBOutlet UIView *viewPlace; // 制御パネルの配置場所
}
- (IBAction)playOrPause; // 再生と一時停止
- (IBAction)skipToNext; // 次の曲にスキップ
- (IBAction)skipToPrevious; // 前の曲にスキップ
- (IBAction)flipToMoreSide; // 裏側を表示
- (IBAction)flipToMainSide; // 表側を表示
@end
#import <MediaPlayer/MediaPlayer.h> // MediaPlayerフレームワークを使用
@interface PanelController : NSObject {
MPMusicPlayerController *player; // 音楽制御用プレイヤ
// 制御パネルの表側
IBOutlet UIView *viewMainSide; // 表側の下地
IBOutlet UILabel *labelSongTitle; // 曲名表示
IBOutlet UILabel *labelAlbumTitle; // アルバム名表示
IBOutlet UILabel *labelArtist; // アーティスト名表示
// 制御パネルの裏側
IBOutlet UIView *viewMoreSide; // 裏側の下地
IBOutlet UIImageView *imageArtWork; // アートワーク表示
// その他
IBOutlet UIView *viewPlace; // 制御パネルの配置場所
}
- (IBAction)playOrPause; // 再生と一時停止
- (IBAction)skipToNext; // 次の曲にスキップ
- (IBAction)skipToPrevious; // 前の曲にスキップ
- (IBAction)flipToMoreSide; // 裏側を表示
- (IBAction)flipToMainSide; // 表側を表示
@end
●フレームワークの追加
iPodライブラリを利用するためMediaPlayerフレームワークを追加します。
Xcodeの『グループとファイル』ペインの『Frameworks』を右クリックして、コンテキストメニューから『追加』→『既存のフレームワーク』を選択し、MediaPlayer.frameworkを追加します。
●アウトレットとアクションの接続
Xcodeでの変更を保存し、Interface Builderでアウトレットとアクションの接続を行います。
まずPanelControllerクラスのインスタンスを追加するため、LibraryウィンドウからObjectをDocumentウィンドウにドラッグ&ドロップします。
Documentウィンドウの追加したObjectを選択した状態で、InspectorウィンドウのIdentityタブを開き、『Class Identity』の『Class』を『Panel Controller』にします。
InspectorウィンドウのConnectionsタブを開き、アウトレットとアクションを接続します。
ボタン類のアクションは全て『Touch Up Inside』に設定します。
●アクションメソッドの実装
PanelController.mソースファイルにメソッドを実装します。
(太字が追加した部分)
#import "PanelController.h"
@implementation PanelController
- (void)updateView {
// 現在再生中の曲を取得
MPMediaItem *curItem = [player nowPlayingItem];
// 曲情報の取得とビューへの反映(曲名/アルバム名/アーティスト名)
labelSongTitle.text = [curItem valueForProperty:MPMediaItemPropertyTitle];
labelAlbumTitle.text = [curItem valueForProperty:MPMediaItemPropertyAlbumTitle];
labelArtist.text = [curItem valueForProperty:MPMediaItemPropertyArtist];
// アートワークの取得とビューへの反映
MPMediaItemArtwork *artWork;
artWork = [curItem valueForProperty:MPMediaItemPropertyArtwork];
imageArtWork.image = [artWork imageWithSize:imageArtWork.frame.size];
}
- (void)awakeFromNib {
// プレイヤ生成
player = [MPMusicPlayerController iPodMusicPlayer];
// 音楽再生
player.repeatMode = MPMusicRepeatModeAll; // 全曲リピートに設定
player.shuffleMode = MPMusicShuffleModeOff; // シャッフル無しに設定
[player play]; // 再生開始
// 制御パネルの表側を貼り付ける
[viewPlace addSubview:viewMainSide];
// 現在再生中の曲の情報を画面に表示する
[self updateView];
// 通知センターのインスタンスを取得
NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter];
// 再生曲が変化した時の通知先を登録
[noteCenter addObserver:self selector:@selector(didItemChanged:) name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification object:player];
// 通知の開始を指示
[player beginGeneratingPlaybackNotifications];
}
// 再生/一時停止
- (IBAction)playOrPause {
// 現在の再生状態を取得
MPMusicPlaybackState state = player.playbackState;
// 一時停止中なら再生
if (state == MPMusicPlaybackStatePaused) {
[player play];
}
// 再生中なら一時停止
else if (state == MPMusicPlaybackStatePlaying) {
[player pause];
}
}
// 次の曲へスキップ
- (IBAction)skipToNext {
[player skipToNextItem];
}
// 前の曲へスキップ
- (IBAction)skipToPrevious {
// 再生位置が曲の先頭から3秒未満なら前の曲へスキップ
if (player.currentPlaybackTime < 3.0) {
[player skipToPreviousItem];
}
// 再生位置が曲の先頭から3秒以上なら曲の先頭にスキップ
else {
[player skipToBeginning];
}
}
- (void)didItemChanged:(NSNotification *)aNote {
// 通知名を取得
NSString *noteName = [aNote name];
// 通知が『現在再生中の曲の変化』なら画面を更新
if ([noteName isEqualToString:MPMusicPlayerControllerNowPlayingItemDidChangeNotification]) {
[self updateView]; // 曲情報表示を更新
}
}
- (void)dealloc {
// 通知の停止を指示
[player endGeneratingPlaybackNotifications];
// 通知センターのインスタンスを取得
NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter];
// 通知先の登録を解除
[noteCenter removeObserver:self];
[super dealloc];
}
- (IBAction)flipToMoreSide {
// アニメーションの準備
[UIView setAnimationsEnabled:YES];
[UIView beginAnimations:@"Flip" context:nil];
[UIView setAnimationDuration:0.5f];
// トランジションアニメーションの設定
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:viewPlace cache:YES];
// ビューの貼り替え
[viewMainSide removeFromSuperview]; // 表側の制御パネルを外す
[viewPlace addSubview:viewMoreSide]; // 裏側の制御パネルを貼り付ける
// アニメーション実行
[UIView commitAnimations];
}
- (IBAction)flipToMainSide {
// アニメーションの準備
[UIView setAnimationsEnabled:YES];
[UIView beginAnimations:@"Flip" context:nil];
[UIView setAnimationDuration:0.5f];
// トランジションアニメーションの設定
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:viewPlace cache:YES];
// ビューの貼り替え
[viewMoreSide removeFromSuperview]; // 裏側の制御パネルを外す
[viewPlace addSubview:viewMainSide]; // 表側の制御パネルを貼り付ける
// アニメーション実行
[UIView commitAnimations];
}
@end
@implementation PanelController
- (void)updateView {
// 現在再生中の曲を取得
MPMediaItem *curItem = [player nowPlayingItem];
// 曲情報の取得とビューへの反映(曲名/アルバム名/アーティスト名)
labelSongTitle.text = [curItem valueForProperty:MPMediaItemPropertyTitle];
labelAlbumTitle.text = [curItem valueForProperty:MPMediaItemPropertyAlbumTitle];
labelArtist.text = [curItem valueForProperty:MPMediaItemPropertyArtist];
// アートワークの取得とビューへの反映
MPMediaItemArtwork *artWork;
artWork = [curItem valueForProperty:MPMediaItemPropertyArtwork];
imageArtWork.image = [artWork imageWithSize:imageArtWork.frame.size];
}
- (void)awakeFromNib {
// プレイヤ生成
player = [MPMusicPlayerController iPodMusicPlayer];
// 音楽再生
player.repeatMode = MPMusicRepeatModeAll; // 全曲リピートに設定
player.shuffleMode = MPMusicShuffleModeOff; // シャッフル無しに設定
[player play]; // 再生開始
// 制御パネルの表側を貼り付ける
[viewPlace addSubview:viewMainSide];
// 現在再生中の曲の情報を画面に表示する
[self updateView];
// 通知センターのインスタンスを取得
NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter];
// 再生曲が変化した時の通知先を登録
[noteCenter addObserver:self selector:@selector(didItemChanged:) name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification object:player];
// 通知の開始を指示
[player beginGeneratingPlaybackNotifications];
}
// 再生/一時停止
- (IBAction)playOrPause {
// 現在の再生状態を取得
MPMusicPlaybackState state = player.playbackState;
// 一時停止中なら再生
if (state == MPMusicPlaybackStatePaused) {
[player play];
}
// 再生中なら一時停止
else if (state == MPMusicPlaybackStatePlaying) {
[player pause];
}
}
// 次の曲へスキップ
- (IBAction)skipToNext {
[player skipToNextItem];
}
// 前の曲へスキップ
- (IBAction)skipToPrevious {
// 再生位置が曲の先頭から3秒未満なら前の曲へスキップ
if (player.currentPlaybackTime < 3.0) {
[player skipToPreviousItem];
}
// 再生位置が曲の先頭から3秒以上なら曲の先頭にスキップ
else {
[player skipToBeginning];
}
}
- (void)didItemChanged:(NSNotification *)aNote {
// 通知名を取得
NSString *noteName = [aNote name];
// 通知が『現在再生中の曲の変化』なら画面を更新
if ([noteName isEqualToString:MPMusicPlayerControllerNowPlayingItemDidChangeNotification]) {
[self updateView]; // 曲情報表示を更新
}
}
- (void)dealloc {
// 通知の停止を指示
[player endGeneratingPlaybackNotifications];
// 通知センターのインスタンスを取得
NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter];
// 通知先の登録を解除
[noteCenter removeObserver:self];
[super dealloc];
}
- (IBAction)flipToMoreSide {
// アニメーションの準備
[UIView setAnimationsEnabled:YES];
[UIView beginAnimations:@"Flip" context:nil];
[UIView setAnimationDuration:0.5f];
// トランジションアニメーションの設定
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:viewPlace cache:YES];
// ビューの貼り替え
[viewMainSide removeFromSuperview]; // 表側の制御パネルを外す
[viewPlace addSubview:viewMoreSide]; // 裏側の制御パネルを貼り付ける
// アニメーション実行
[UIView commitAnimations];
}
- (IBAction)flipToMainSide {
// アニメーションの準備
[UIView setAnimationsEnabled:YES];
[UIView beginAnimations:@"Flip" context:nil];
[UIView setAnimationDuration:0.5f];
// トランジションアニメーションの設定
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:viewPlace cache:YES];
// ビューの貼り替え
[viewMoreSide removeFromSuperview]; // 裏側の制御パネルを外す
[viewPlace addSubview:viewMainSide]; // 表側の制御パネルを貼り付ける
// アニメーション実行
[UIView commitAnimations];
}
@end
本書の説明の順序ですと、awakeFromNibメソッド内で呼び出すupdateViewメソッドの記述が後になってビルド時にエラーになりますので、updateViewメソッドはawakeFromNibメソッドの前に記述してください。
●ビルドと実行
本書内でも解説されているように、iPhone本体のiPodアプリケーションで再生曲が選択されていない場合(音楽ではなくビデオを再生した後など)では音楽が再生されず、アートワークも含めて楽曲情報も表示されません。
アートワークは楽曲にアートワークが指定されていない場合に『noimage.png』が表示されるので、楽曲が指定されていない場合は何も表示されません。
再生制御の3つのボタンも機能せず、動作が確認できるのは制御パネルを切り替える『More』と『Back』ボタンのみです。
この場合、iPodアプリケーションで一度音楽を再生してから再度MusicPlayerアプリケーションを立ち上げると、起動と同時に選択されている音楽が再生されます。
参考文献
基礎からのiOS SDK (2010/10/09) 鶴薗 賢吾、松浦 健一郎 他 商品詳細を見る |