fc2ブログ

音楽プレイヤの作成

2010. 07. 21
基礎からのiPhone SDK 改訂版』も今回の『iPodライブラリアクセス+音楽プレイヤ』が最後のお題となります。


●音楽プレイヤの概要

表題の通りMedia Playerフレームワークを使ってiPodライブラリにアクセスし、自身のアプリケーションから楽曲を再生するものです。

画面構成は下図のようなインターフェイスになっています。

553

背景は(スライドショーのBGMとしての利用を前提としていますが)ただの画像です。

画面下方にあるパネルは、再生中の曲名、アルバム名、アーティスト名をラベルで表示し、『前の曲へ戻る』『再生/一時停止』『次の曲へ進む』ボタンで再生曲を制御します。

『More』と『Back』ボタンでパネルが回転して切り替えるようになっており、裏面にはアートワークを表示します。

554


●プロジェクトの作成

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フォルダに使用する画像を登録します。

556


2)背景画像の設定

MainWindow.xibをダブルクリックしてInterface Builderを開きます。

LibraryウィンドウからImage Viewをドラッグ&ドロップでViewウィンドウに配置し、InspectorウィンドウのAttributesタブのImageでBackground.pngまたは背景用の画像を選択します。

557


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としています。

558

Attributesタブの『Image View』の『Image』で制御パネルの背景画像をbg.pngにします。

続いてUIImageViewの背景画像を消去するため、『View』の『Background』で『Colors』ウィンドウでOpacityを0%にします。

559

それと『Drawing』のOpaqueのチェックを外し、透明化を有効にします。

『Clear Context Before Drawing(前の描画内容をクリアしてから再描画する)』のチェックは今回の場合どちらでも構いません。

制御パネルへの操作を受け付けられるように、『Interaction』の『User Interaction Enable(ユーザ操作を有効にする)』にチェックを入れます。

560

メインウィンドウのレイアウトはこれで完了です。

561


4)制御パネルのレイアウト

実際の制御パネルには表と裏があり、メインウィンドウ上に貼り付けるのではなく、別のビューでレイアウトを組んでプログラム上で貼り付ける手法になっています。

まずLibraryウィンドウからViewをドラッグ&ドロップでDocumentウィンドウに2つ加え、Viewの名前をクリックし、識別のため『View Main Side』と『View More Side』に変更します。

562

それぞれをダブルクリックして開き、InspectorウィンドウのSizeタブでW:260、H:180に設定します。

563

まずMain Sideのレイアウトを行います。

View Main SideのViewウィンドウに、LibraryウィンドウからLabelを3つ、Round Rect Buttonを4つドラッグ&ドロップで配置します。
(ここでの位置やサイズはおおよそで構いません)

564

作業を円滑に進めるため、先に識別名を入力します。

ラベルは、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』とします。

565

次に位置とサイズをInspectorウィンドウのSizeタブで下表のように設定します。

NameXYWH
Label (Song Name)51325023
Label (Album Name)53925021
Label (Artist Name)56425023
Custom Button (Prev)11997037
Custom Button (Play)95997037
Custom Button (Next)180997037
Round Rect Button (More)1801477224

続いてAttributesタブでの設定を行います。

まずビューの背景を透明化するため、DocumentウィンドウでView Main Sideを選択し、『View』の『Background』を『Clear Color』にし、『Drawing』の『Opaque』のチェックを外します。

566

ラベルは3つとも『Label』の『Layout』で『Alignment』を中央に、『View』の『Mode』を『Scale To Fill』にします。

『Label』の『Font』は、Song Nameは『Helvetica Bold, 17.0』に、Album NameとArtist Nameは『Helvetica, 14.0』に設定します。

567

568

再生制御のボタンは、『Button』の『Background』を3つとも『bgButton.png』にし、『Image』はそれぞれ左から『prev.png』『play.png』『next.png』と設定します。

569

裏面にするボタンは既に『Title』の設定も済んでいるので、そのままです。

Main Sideのレイアウトはこれで完了です。

571

続いて裏面になる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つドラッグ&ドロップで配置します。
(ここでの位置やサイズはおおよそで構いません)

572

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』は今回何も仕掛けをしないのですが後々のことを考えて一応チェックを入れています。

573

Round Rect Buttonは、『Button』の『Title』を『Back』にするだけです。

574

More Sideのレイアウトはこれで完了です。

575

この時点でのDocumentウィンドウの構成は下図のようになります。

576


●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

577


●フレームワークの追加

iPodライブラリを利用するためMediaPlayerフレームワークを追加します。

Xcodeの『グループとファイル』ペインの『Frameworks』を右クリックして、コンテキストメニューから『追加』→『既存のフレームワーク』を選択し、MediaPlayer.frameworkを追加します。

578


●アウトレットとアクションの接続

Xcodeでの変更を保存し、Interface Builderでアウトレットとアクションの接続を行います。

まずPanelControllerクラスのインスタンスを追加するため、LibraryウィンドウからObjectをDocumentウィンドウにドラッグ&ドロップします。

Documentウィンドウの追加したObjectを選択した状態で、InspectorウィンドウのIdentityタブを開き、『Class Identity』の『Class』を『Panel Controller』にします。

579

InspectorウィンドウのConnectionsタブを開き、アウトレットとアクションを接続します。

ボタン類のアクションは全て『Touch Up Inside』に設定します。

580


●アクションメソッドの実装

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

581

本書の説明の順序ですと、awakeFromNibメソッド内で呼び出すupdateViewメソッドの記述が後になってビルド時にエラーになりますので、updateViewメソッドはawakeFromNibメソッドの前に記述してください。


●ビルドと実行

本書内でも解説されているように、iPhone本体のiPodアプリケーションで再生曲が選択されていない場合(音楽ではなくビデオを再生した後など)では音楽が再生されず、アートワークも含めて楽曲情報も表示されません。

582

583

アートワークは楽曲にアートワークが指定されていない場合に『noimage.png』が表示されるので、楽曲が指定されていない場合は何も表示されません。

再生制御の3つのボタンも機能せず、動作が確認できるのは制御パネルを切り替える『More』と『Back』ボタンのみです。

この場合、iPodアプリケーションで一度音楽を再生してから再度MusicPlayerアプリケーションを立ち上げると、起動と同時に選択されている音楽が再生されます。



参考文献

基礎からのiOS SDK基礎からのiOS SDK
(2010/10/09)
鶴薗 賢吾、松浦 健一郎 他

商品詳細を見る

0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
02 | 2024/03 | 04
Sun Mon Tue Wed Thu Fri Sat
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -
Recent Articles
Wish List
iOS/iPadOS Devices
Twine
Twine Reference
1. 序章
2. はじめに
2.1. Twineのインストール
2.2. 基本コンセプト
2.3. Twineを使いこなす
2.4. Twineのアップデート
2.5. Twineのアンインストール
2.6. Twineの古いバージョンを使う
3. ストーリーライブラリを使う
3.1. ストーリーの表示
3.2. ストーリーの作成、コピー、インポート
3.3. ストーリーの編集
3.4. ストーリー名の変更
3.5. ストーリーのアーカイブとエクスポート
3.6. ストーリーの削除
3.7. ストーリーへのタグ付け
3.8. ライブラリの場所を変更する
4. ストーリーの編集
4.1. ストーリーマップのナビゲーション
4.2. 取り消しとやり直し
4.3. パッセージの選択と移動
4.4. パッセージの編集
4.5. パッセージのリンク
4.6. パッセージの削除
4.7. パッセージのタグ付け
4.8. テキストの検索と置換
4.9. ストーリー名の変更
4.10. ストーリーフォーマットの変更
4.11. ストーリーの統計の表示
4.12. ストーリーのJavaScriptとCSSを編集する
5. 作品の公開出力
5.1. ストーリーのテスト
5.2. ストーリーの校正
5.3. ストーリーのプレイ
5.4. ストーリーの公開出力
5.5. スクラッチフォルダ
6. ストーリーフォーマットの管理
6.1. ストーリーフォーマットの表示
6.2. デフォルトのストーリーフォーマットの変更
6.3. 校正フォーマットの変更
6.4. ストーリーフォーマットの追加
6.5. ストーリーフォーマットの削除
6.6. ストーリーフォーマットの拡張機能を無効にする
6.7. Twineがストーリーフォーマットのバージョンを管理する方法
7. Twineのカスタマイズ
7.1. 環境設定の設定
7.2. コマンドラインスイッチ
7.3. 高度なカスタマイズ
8. 制限事項
8.1. 大きなストーリー
8.2. ストーリーの組み合わせ
8.3. ストーリーの共同編集
8.4. 画像とマルチメディアの使用
8.5. ソースコントロールでの作業
9. 問題のトラブルシューティング
9.1. バックアップ
9.2. ローカルストレージの直接表示
9.3. 編集中にエラーメッセージが表示される場合
9.4. Twineが起動しない場合
9.5. Twineがあなたのストーリーを失ったら
9.6. ストーリーが破損している場合
9.7. Twineの外観に不具合がある場合
10. リリースノート
10.1. バージョン 2.8
10.2. バージョン 2.7
10.3. バージョン 2.6
10.4. バージョン 2.5
10.5. バージョン 2.4
10.6. バージョン 2.3
10.7. バージョン 2.2
10.8. バージョン 2.1
10.9. バージョン 2.0
10.10. バージョン 1.0
10.11. Tweebox バージョン

Twine Cookbook
詳解Swift
詳解Swift第5版(01)〜Swiftでプログラミング
詳解Swift第5版(02)〜関数
詳解Swift第5版(03)〜構造体
詳解Swift第5版(04)〜オプショナル
詳解Swift第5版(05)〜プロトコル
詳解Swift第5版(06)〜基本的なデータ型
詳解Swift第5版(07)〜パターン
詳解Swift第5版(08)〜クラスと継承
詳解Swift第5版(09)〜メモリ管理
詳解Swift第5版(10)〜拡張
詳解Swift第5版(11)〜エラー処理
詳解Swift第5版(12)〜クロージャ
詳解Swift第5版(13)〜ジェネリクス
詳解Swift第5版(14)〜メモリへのアクセスとポインタ
詳解Swift第5版(15)〜カスタム属性とDSL記法
詳解Swift第5版(16)〜GUI との連携

詳解Swift第4版(01)〜Swiftでプログラミング
詳解Swift第4版(02)〜関数
詳解Swift第4版(03)〜構造体
詳解Swift第4版(06)〜基本的なデータ型
詳解Swift第4版(07)〜パターン
詳解Swift第4版(08)〜クラスと継承
詳解Swift第4版(09)〜メモリ管理
詳解Swift第4版(10)〜拡張
詳解Swift第4版(11)〜エラー処理
詳解Swift第4版(12)〜クロージャ
詳解Swift第4版(13)〜ジェネリクス

詳解Swift第3版(01)〜Swiftでプログラミング
詳解Swift第3版(02)〜関数
詳解Swift第3版(03)〜構造体
詳解Swift第3版(05)〜基本的なデータ型
詳解Swift第3版(06)〜パターン
詳解Swift第3版(07)〜演算子
詳解Swift第3版(08)〜クラスと継承
詳解Swift第3版(09)〜メモリ管理
詳解Swift第3版(10)〜プロトコル
詳解Swift第3版(11)〜拡張
詳解Swift第3版(12)〜エラー処理
詳解Swift第3版(13)〜クロージャ
詳解Swift第3版(14)〜ジェネリクス

詳解Swift改訂版(01)〜Swiftでプログラミング
詳解Swift改訂版(02)〜関数
詳解Swift改訂版(03)〜構造体
詳解Swift改訂版(04)〜オプショナル
詳解Swift改訂版(05)〜基本的なデータ型
詳解Swift改訂版(06)〜パターン
詳解Swift改訂版(07)〜演算子
詳解Swift改訂版(08)〜クラスと継承
詳解Swift改訂版(09)〜メモリ管理
詳解Swift改訂版(10)〜プロトコル
詳解Swift改訂版(11)〜拡張
詳解Swift改訂版(12)〜エラー処理
詳解Swift改訂版(13)〜クロージャ
詳解Swift改訂版(14)〜ジェネリクス

詳解Swift(1)〜Swiftでプログラミング
詳解Swift(2)〜関数
詳解Swift(3)〜構造体
詳解Swift(4)〜オプショナル
詳解Swift(5)〜基本的なデータ型
詳解Swift(6)〜パターン
詳解Swift(7)〜演算子
詳解Swift(8)〜クラスと継承
詳解Swift(9)〜メモリ管理
詳解Swift(10)〜プロトコル
詳解Swift(11)〜拡張
詳解Swift(12)〜クロージャ
詳解Swift(13)〜ジェネリクス
詳解Swift(14)〜C/Objective-Cとのデータ受け渡し
Swift
Site Map
Apple Music


Categories
Tips
ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
QR Code
QR
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ

Visitors