DJの選曲にもレコメンドがあると楽じゃないか?それTraktorでもできませんかね!? Vol.2

おはようございます

KAI-YOUエンジニアのコウベ(@cabbagekobe)です。

というわけで前回の記事の続きになります。 kai-you-tech.hatenablog.com

そして改めて10月29日にPOP TECH PARTYというイベントが開かれます。

POP TECH PARTYとは

kai-you.net

今まで来たことある人も、行けなかったようという方も、第4回ポプテクへ、ぜひ1周年のお祝いにきてください! 参加DJは随時おしらせしまーす!

参加表明をFacebookからしていただけると超嬉しい!! https://www.facebook.com/poptechparty/


という感じのイベントです。私もやるぞ!

楽しいイベントになること間違いなし!みんな来てください!!

ということで続き…

前回はとりあえず楽曲とDjay上のMatchタブに出てきた楽曲を比べてみましたがデータが少なすぎてわからないというのが正直な気持ち。

ということでやっていきたいことはデータの収集です。

最終的にやりたいことの筋道としてはこのように考えています。

  1. Traktorにてデータを収集したいトラックのプレイリストを作る
  2. 上記プレイリストのトラックがSpotifyにあるのか検索する
  3. Spotifyに会った場合はAudio Featuresに楽曲IDを投げる
  4. 手に入ったデータをDBに入れる
  5. TraktorでのDJ中に上記のDBにアクセスして情報を取得する

1. プレイリスト作成

というわけで適当にプレイリストを作りました。前回も起点にしたIZ*ONEの日本デビューシングル、好きと言わせたいを含んだプレイリストを適当に作りました。

f:id:KAI-YOU:20191018212831p:plain

作ったプレイリストをExportしていく。

f:id:KAI-YOU:20191021173245p:plain
f:id:KAI-YOU:20191021173434p:plain

Copy Tracks To Destinationのチェックは外しましょうね。

2. NMLファイルの読み込み

Traktorのプレイリストなどに使われるnmlファイルを読み込みましょう。

github.com

こちらを使います。

Gemfileなり、gem installなりで上記をインストールして、こんな感じのコードを書きましょう。

require 'traktor/nml'
require 'pp'

Traktor::NML.parse File.open("path/to/playlist.nml")
playlist = Traktor::NML.load "path/to/playlist.nml"

pp playlist

はい。下記の出力が得られましたね。(出力データ整理済み)

#<Traktor::NML::Playlist:0x00007fb43b8aa740 @tracks= [
  #<Traktor::NML::Track:0x00007fb43b896268
    @album={:title=>"好きと言わせたい (Type B)", :track=>"1"},
    @artist="IZ*ONE",
    @bpm=132.001007,
    @cues=[
      #<Traktor::NML::Cue:0x00007fb43b8975a0 @hotcue=0, @length=0.0, @name="1.16.32. - 32.", @repeats=-1, @start=633.25578, @type=3>,
      #<Traktor::NML::Cue:0x00007fb43b896b78 @hotcue=4, @length=0.0, @name="n.n.", @repeats=-1, @start=1087.797767, @type=4>,
      #<Traktor::NML::Cue:0x00007fb43b8962b8 @hotcue=3, @length=0.0, @name="n.n.", @repeats=-1, @start=88359.859206, @type=0>
    ],
    @genre="J-POP",
    @key="9d",
    @label="",
    @musical_key="8",
    @playtime=239.0,
    @primarykey="Macintosh HD/:Users/:cabbagekobe/:Music/:iTunes/:iTunes Media/:Music/:IZ_ONE/:好きと言わせたい (Type B)/:01 好きと言わせたい.mp3",
    @release_date=#<Date: 2019-01-01 ((2458485j,0s,0n),+0s,2299161j)>,
    @title="好きと言わせたい"
  >,
  #<Traktor::NML::Track:0x00007fb43b8aaa10
    @album={:title=>"ドレミソラシド [通常盤]", :track=>"1"},
    @artist="日向坂46",
    @bpm=132.991379,
    @cues=[
      #<Traktor::NML::Cue:0x00007fb43b8abd20 @hotcue=0, @length=0.0, @name="8.32. - 64. - 32", @repeats=-1, @start=7660.120709, @type=3>,
      #<Traktor::NML::Cue:0x00007fb43b8ab6e0 @hotcue=4, @length=0.0, @name="Beat Marker", @repeats=-1, @start=11269.377222, @type=4>,
      #<Traktor::NML::Cue:0x00007fb43b8ab0a0 @hotcue=2, @length=0.0, @name="n.n.", @repeats=-1, @start=92477.648756, @type=0>,
      #<Traktor::NML::Cue:0x00007fb43b8aaa60 @hotcue=3, @length=0.0, @name="n.n.", @repeats=-1, @start=124960.95737, @type=0>
    ],
    @genre="Pop",
    @key="9m",
    @label="",
    @musical_key="17",
    @playtime=305.0,
    @primarykey="Macintosh HD/:Users/:cabbagekobe/:Music/:iTunes/:iTunes Media/:Music/:日向坂46/:ドレミソラシド [通常盤]/:01 ドレミソラシド.mp3",
    @release_date=#<Date: 2019-01-01 ((2458485j,0s,0n),+0s,2299161j)>,
    @title="ドレミソラシド"
  >,
  #<Traktor::NML::Track:0x00007fb43d8b8d98
    @album={:title=>"ぐるぐるカーテン", :track=>"1"},
    @artist="乃木坂46",
    @bpm=132.0,
    @cues=[
      #<Traktor::NML::Cue:0x00007fb43d8baa08 @hotcue=0, @length=0.0, @name="8.32.", @repeats=-1, @start=423.779091, @type=3>,
      #<Traktor::NML::Cue:0x00007fb43d8b8e60 @hotcue=4, @length=0.0, @name="Beat Marker", @repeats=-1, @start=4060.142727, @type=4>
    ],
    @genre="Pop",
    @key="3d",
    @label="",
    @musical_key="2",
    @playtime=245.0,
    @primarykey="Macintosh HD/:Users/:cabbagekobe/:Music/:iTunes/:iTunes Media/:Music/:乃木坂46/:ぐるぐるカーテン/:01 ぐるぐるカーテン.mp3",
    @release_date=#<Date: 2012-01-01 ((2455928j,0s,0n),+0s,2299161j)>,
    @title="ぐるぐるカーテン"
  >,
  #<Traktor::NML::Track:0x00007fb43b85cd60
    @album={:title=>"ディスコの神様", :track=>"1"},
    @artist="tofubeats Feat. 藤井隆",
    @bpm=119.995003,
    @cues=[
      #<Traktor::NML::Cue:0x00007fb43b85f4c0 @hotcue=0, @length=0.0, @name="0.32 - 32.", @repeats=-1, @start=428.537, @type=3>,
      #<Traktor::NML::Cue:0x00007fb43b85d5f8 @hotcue=4, @length=0.0, @name="Beat Marker", @repeats=-1, @start=428.537, @type=4>,
      #<Traktor::NML::Cue:0x00007fb43b85cdd8 @hotcue=3, @length=0.0, @name="n.n.", @repeats=-1, @start=112433.201297, @type=0>
    ],
    @genre="Electronica",
    @key="9d",
    @label="",
    @musical_key="8",
    @playtime=294.0,
    @primarykey="Macintosh HD/:Users/:cabbagekobe/:Music/:iTunes/:iTunes Media/:Music/:tofubeats Feat. 藤井隆/:ディスコの神様/:01 ディスコの神様.mp3",
    @release_date=#<Date: 2013-01-01 ((2456294j,0s,0n),+0s,2299161j)>,
    @title="ディスコの神様"
  >
]>

3. SpotifyAPIを使う

まずはSpotifyAPIを利用するには、アカウント作ってclient_id, client_secretを発行する必要があります。

https://developer.spotify.com

こちらから適当なアプリを作ってそこからclient_id, client_secretを取得して使いましょう。

RSpotifyを使う

RubyでのSpotify APIのラッパーとしてRSpotifyというものがあります。

github.com

これを使いましょう。

Gemfileなり、gem installなりで上記をインストール。

上記gemのREADMEを参考に下記コードを実行します。

またSpotify API はすべての API に authenticateが必要になっています。 (client_id, client_secret)は上記で取得したやつをいれてね。

require 'rspotify'
require 'pp'

RSpotify.authenticate(client_id, client_secret)

tracks = RSpotify::Track.search('好きと言わせたい')
track = tracks.first

pp track

トラック情報取得できました!(出力データ整理済み)

#<RSpotify::Track:0x00007fe0f148ce28 @album=
  #<RSpotify::Album:0x00007fe0f1466d90
    @album_type="single",
    @artists=[
      #<RSpotify::Artist:0x00007fe0f1447a58
        @external_urls={"spotify"=>"https://open.spotify.com/artist/5r1tUTxVSgvBHnoDuDODPH"},
        @followers=nil,
        @genres=nil,
        @href="https://api.spotify.com/v1/artists/5r1tUTxVSgvBHnoDuDODPH",
        @id="5r1tUTxVSgvBHnoDuDODPH",
        @images=nil,
        @name="IZ*ONE",
        @popularity=nil,
        @top_tracks={},
        @type="artist",
        @uri="spotify:artist:5r1tUTxVSgvBHnoDuDODPH"
      >
    ],
    @available_markets=[
      "AD", "AE", "AR", "AT", "AU", "BE", "BG", "BH", "BO", "BR", "CA", "CH",
      "CL", "CO", "CR", "CY", "CZ", "DE", "DK", "DO", "DZ", "EC", "EE", "EG",
      "ES", "FI", "FR", "GB", "GR", "GT", "HK", "HN", "HU", "ID", "IE", "IL",
      "IN", "IS", "IT", "JO", "KW", "LB", "LI", "LT", "LU", "LV", "MA", "MC",
      "MT", "MX", "MY", "NI", "NL", "NO", "NZ", "OM", "PA", "PE", "PH", "PL",
      "PS", "PT", "PY", "QA", "RO", "SA", "SE", "SG", "SK", "SV", "TH", "TN",
      "TR", "TW", "US", "UY", "VN", "ZA"
    ],
    @copyrights=nil,
    @external_ids=nil,
    @external_urls={"spotify"=>"https://open.spotify.com/album/6esOExMaYIWvttAQYdn3Gb"},
    @genres=nil,
    @href="https://api.spotify.com/v1/albums/6esOExMaYIWvttAQYdn3Gb",
    @id="6esOExMaYIWvttAQYdn3Gb",
    @images=[
      {"height"=>640, "url"=> "https://i.scdn.co/image/ab67616d0000b2732d7ca7730cc00d57bfdab861", "width"=>640},
      {"height"=>300, "url"=> "https://i.scdn.co/image/ab67616d00001e022d7ca7730cc00d57bfdab861", "width"=>300},
      {"height"=>64, "url"=> "https://i.scdn.co/image/ab67616d000048512d7ca7730cc00d57bfdab861", "width"=>64}
    ],
    @label=nil,
    @name="好きと言わせたい (Type A)",
    @popularity=nil,
    @release_date="2019-02-05",
    @release_date_precision="day",
    @total_tracks=nil,
    @tracks_cache=nil,
    @type="album",
    @uri="spotify:album:6esOExMaYIWvttAQYdn3Gb"
  >,
  @artists=[
    #<RSpotify::Artist:0x00007fe0f1447760
      @external_urls={"spotify"=>"https://open.spotify.com/artist/5r1tUTxVSgvBHnoDuDODPH"},
      @followers=nil,
      @genres=nil,
      @href="https://api.spotify.com/v1/artists/5r1tUTxVSgvBHnoDuDODPH",
      @id="5r1tUTxVSgvBHnoDuDODPH",
      @images=nil,
      @name="IZ*ONE",
      @popularity=nil,
      @top_tracks={},
      @type="artist",
      @uri="spotify:artist:5r1tUTxVSgvBHnoDuDODPH"
    >
  ],
  @available_markets=[
    "AD", "AE", "AR", "AT", "AU", "BE", "BG", "BH", "BO", "BR", "CA", "CH",
    "CL", "CO", "CR", "CY", "CZ", "DE", "DK", "DO", "DZ", "EC", "EE", "EG",
    "ES", "FI", "FR", "GB", "GR", "GT", "HK", "HN", "HU", "ID", "IE", "IL",
    "IN", "IS", "IT", "JO", "KW", "LB", "LI", "LT", "LU", "LV", "MA", "MC",
    "MT", "MX", "MY", "NI", "NL", "NO", "NZ", "OM", "PA", "PE", "PH", "PL",
    "PS", "PT", "PY", "QA", "RO", "SA", "SE", "SG", "SK", "SV", "TH", "TN",
    "TR", "TW", "US", "UY", "VN", "ZA"
  ],
  @context_type=nil,
  @disc_number=1,
  @duration_ms=239333,
  @explicit=false,
  @external_ids={"isrc"=>"JPPO01806807"},
  @external_urls={"spotify"=>"https://open.spotify.com/track/7nimCdASI4W4j5C4zqvKO5"},
  @href="https://api.spotify.com/v1/tracks/7nimCdASI4W4j5C4zqvKO5",
  @id="7nimCdASI4W4j5C4zqvKO5",
  @is_playable=nil,
  @linked_from=nil,
  @name="好きと言わせたい",
  @played_at=nil,
  @popularity=49,
  @preview_url=nil,
  @track_number=1,
  @type="track",
  @uri="spotify:track:7nimCdASI4W4j5C4zqvKO5"
>

データは取れる!
取ったデータの曲idをもう一回SpotifyAPIに投げましょう。
下記のような感じ。

require 'rspotify'
require 'pp'

RSpotify.authenticate(client_id, client_secret)

tracks = RSpotify::Track.search('好きと言わせたい')
track = tracks.first

audio_features = RSpotify::AudioFeatures.find(track.id)

pp audio_features

うおー!という感じでデータが取得できたぞー!!!(出力データ整理済み)

#<RSpotify::AudioFeatures:0x00007fd388132f78
 @acousticness=0.122,
 @analysis_url="https://api.spotify.com/v1/audio-analysis/7nimCdASI4W4j5C4zqvKO5",
 @danceability=0.532,
 @duration_ms=239333,
 @energy=0.938,
 @external_urls=nil,
 @href=nil,
 @id="7nimCdASI4W4j5C4zqvKO5",
 @instrumentalness=0,
 @key=8,
 @liveness=0.245,
 @loudness=-1.409,
 @mode=1,
 @speechiness=0.0568,
 @tempo=132.023,
 @time_signature=4,
 @track_href="https://api.spotify.com/v1/tracks/7nimCdASI4W4j5C4zqvKO5",
 @type="audio_features",
 @uri="spotify:track:7nimCdASI4W4j5C4zqvKO5",
 @valence=0.716
>

4. というわけでまとめたやつがこんな感じ。

require 'rspotify'
require 'pp'
require 'traktor/nml'

RSpotify.authenticate(client_id, client_secret)

Traktor::NML.parse File.open("path/to/playlist.nml")
playlist = Traktor::NML.load "path/to/playlist.nml"

playlist.each{|track, value|
  tracks = RSpotify::Track.search(track.title)

  audio_features = RSpotify::AudioFeatures.find(tracks.first.id)

  pp audio_features
  pp "--------------------------------------------"
}

上記コードで、NMLファイルからSpotifyの楽曲情報を取得って感じになります。(エラー周りの処理は必要ですね…)

というわけで次回はこいつらをDBにいれてTraktorから参照していくぞ〜〜〜〜!!!

DJの選曲にもレコメンドがあると楽じゃないか?それTraktorでもできませんかね!?

おはようございます。みなさまはDJですか?僕はどうでしょう。

KAI-YOUエンジニアのコウベ(@cabbagekobe)です。

さて、来たる10月29日にPOP TECH PARTYというイベントが開かれます。なんと1周年!

POP TECH PARTYとは

f:id:KAI-YOU:20191007151844j:plain

POP TECH PARTYとは、風呂グラマーとして知られるエンジニア masuidriveと、行政書士でフェチ東京創設者、近ごろはエンジニアと法律家をつなぐ勉強会StudyCode主催者の新井秀美、そしてKAI-YOUが共同開催する音楽イベントです。

「ゆるいつながり」をテーマとして、エンジニアを中心としたDJによる音楽とエンターテインメントを楽しみながら、技術話だけではなく音楽を通したコミュニケーションの場として本パーティを企画しました。

今まで来たことある人も、行けなかったようという方も、第4回ポプテクへ、ぜひ1周年のお祝いにきてください! 参加DJは随時おしらせしまーす!

参加はFacebookから!
https://www.facebook.com/poptechparty/


という感じのイベントですが、私もDJとして末席に名を連ねさせていただいております。

楽しいイベントになること間違いなし!みんな来てください!!

そんなこんなでちょいちょいDJをやらせていただくこともあるのですが、そのDJ周りでやりたいことを書かせていただきます!
ちょっと長くなりそうなので何度かに分けて…

やりたいことの説明!

私はTraktorというソフトを使っていわゆるPCDJという形でDJを行います。

PCDJのソフト自体はいくつかありますが、その中にAlgoriddim(https://www.algoriddim.com)からリリースされているDjayというアプリがあります。
Mac版、Windows版だけではなくiOSAndroidと多数のプラットフォームに対応しております。

f:id:KAI-YOU:20191007173121p:plain

このDjayには特徴的な機能があります。

それは端末内の音源だけではなくSpotifyの音源を使用してDJができるということです!
Spotify Premiumへの加入が必要)

f:id:KAI-YOU:20191007174022j:plain

また、マッチ機能というものがあります。

f:id:KAI-YOU:20191007174110j:plain

マッチ機能とは

楽曲にはアーティスト名・曲名・ジャンルという簡単なものから、キー(音程)や曲の速さ(BPM)などの情報があります。
これらの情報から割り出してくれているのかは不明ですが、マッチのタブを見るとMIXしても同じキーのもの、やBPMが近い楽曲などの不協和音になりにくい曲をリストアップしてくれます。
マッチで表示された曲リストからMIXしていたらスムーズなMIXが行えます!

例えばでIZ*ONEの日本デビューシングル、好きと言わせたいという曲を再生してマッチの画面を開くとこのようになります。

f:id:KAI-YOU:20191007153307j:plain

*ちなみにこちらに関してはThe Echo Nestというサービスを使っているようですね。(元々オープンソースの音楽レコメンデーションエンジンだったThe Echo Nestですが、2014年にSpotifyに買収されています)

これに近いレコメンドをTraktorから使えるようにするというのが目指すところになります!

とはいうもののThe Echo NestのAPIはもう使えなくなっているっぽいです。
The Echo Nest / Spotify Developer

ということで別の手段を使います。

その手段

Spotifyでは各楽曲にたくさんの情報が埋め込まれています。

参考: note.mu

このSpotifyAPIから取得できる楽曲情報からレコメンドの機能を構築出来ないかなぁ。ということです。

まずはSpotifyAPIを使用できるようにすることから始めましょう。(APIの使用に関してもPremium会員のみとなっています)

APIの申し込みはこちら(https://developer.spotify.com)からできますが、今回はAPIのテストをしてみましょう!

Console | Spotify for Developers

こちらでAPIの機能のテストができます。(適宜tokenを取得すれば適度に使えます)

Get Audio Features for a Track

上記の記事でも説明していたdanceability、energyなどはこちらを使って取得できます。

上で使った好きと言わせたいという楽曲ではこのようなデータになります。

{
  "danceability": 0.532,
  "energy": 0.938,
  "key": 8,
  "loudness": -1.409,
  "mode": 1,
  "speechiness": 0.0568,
  "acousticness": 0.122,
  "instrumentalness": 0,
  "liveness": 0.245,
  "valence": 0.716,
  "tempo": 132.023,
  "type": "audio_features",
  "id": "4cb65NgJOppTj6Ip5THclm",
  "uri": "spotify:track:4cb65NgJOppTj6Ip5THclm",
  "track_href": "https://api.spotify.com/v1/tracks/4cb65NgJOppTj6Ip5THclm",
  "analysis_url": "https://api.spotify.com/v1/audio-analysis/4cb65NgJOppTj6Ip5THclm",
  "duration_ms": 239333,
  "time_signature": 4
}

また、その楽曲からDjayのマッチ機能でリストアップされた楽曲情報を取得します。
(複数取得する場合はこちらからやりましょう Get Audio Features for Several Tracks Get Audio Features for Several Tracks

{
  "audio_features": [
    {
      "danceability": 0.697,
      "energy": 0.874,
      "key": 5,
      "loudness": -2.15,
      "mode": 0,
      "speechiness": 0.045,
      "acousticness": 0.0122,
      "instrumentalness": 0,
      "liveness": 0.627,
      "valence": 0.775,
      "tempo": 132.022,
      "type": "audio_features",
      "id": "2FXd6kKCtBIc6UfN1gH1pA",
      "uri": "spotify:track:2FXd6kKCtBIc6UfN1gH1pA",
      "track_href": "https://api.spotify.com/v1/tracks/2FXd6kKCtBIc6UfN1gH1pA",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/2FXd6kKCtBIc6UfN1gH1pA",
      "duration_ms": 213886,
      "time_signature": 4
    },
    {
      "danceability": 0.678,
      "energy": 0.909,
      "key": 6,
      "loudness": -2.361,
      "mode": 1,
      "speechiness": 0.0639,
      "acousticness": 0.108,
      "instrumentalness": 0,
      "liveness": 0.301,
      "valence": 0.774,
      "tempo": 130.998,
      "type": "audio_features",
      "id": "0uLhtkg7MSN0ZFZUwOfE0w",
      "uri": "spotify:track:0uLhtkg7MSN0ZFZUwOfE0w",
      "track_href": "https://api.spotify.com/v1/tracks/0uLhtkg7MSN0ZFZUwOfE0w",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/0uLhtkg7MSN0ZFZUwOfE0w",
      "duration_ms": 249878,
      "time_signature": 4
    },
    {
      "danceability": 0.555,
      "energy": 0.852,
      "key": 6,
      "loudness": -3.761,
      "mode": 1,
      "speechiness": 0.0439,
      "acousticness": 0.557,
      "instrumentalness": 0,
      "liveness": 0.314,
      "valence": 0.652,
      "tempo": 132.078,
      "type": "audio_features",
      "id": "0wRfhRWNX6WEJmxp5ed4Dy",
      "uri": "spotify:track:0wRfhRWNX6WEJmxp5ed4Dy",
      "track_href": "https://api.spotify.com/v1/tracks/0wRfhRWNX6WEJmxp5ed4Dy",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/0wRfhRWNX6WEJmxp5ed4Dy",
      "duration_ms": 270093,
      "time_signature": 4
    },
    {
      "danceability": 0.661,
      "energy": 0.898,
      "key": 7,
      "loudness": -2.482,
      "mode": 1,
      "speechiness": 0.108,
      "acousticness": 0.151,
      "instrumentalness": 0,
      "liveness": 0.118,
      "valence": 0.891,
      "tempo": 130.981,
      "type": "audio_features",
      "id": "4phwwHkDrqeUMPoOY4vI6I",
      "uri": "spotify:track:4phwwHkDrqeUMPoOY4vI6I",
      "track_href": "https://api.spotify.com/v1/tracks/4phwwHkDrqeUMPoOY4vI6I",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/4phwwHkDrqeUMPoOY4vI6I",
      "duration_ms": 194840,
      "time_signature": 4
    },
    {
      "danceability": 0.684,
      "energy": 0.893,
      "key": 6,
      "loudness": -3.266,
      "mode": 1,
      "speechiness": 0.0576,
      "acousticness": 0.113,
      "instrumentalness": 0,
      "liveness": 0.316,
      "valence": 0.81,
      "tempo": 130.963,
      "type": "audio_features",
      "id": "1ptM5l7tbT3QCbvYjtBEpV",
      "uri": "spotify:track:1ptM5l7tbT3QCbvYjtBEpV",
      "track_href": "https://api.spotify.com/v1/tracks/1ptM5l7tbT3QCbvYjtBEpV",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/1ptM5l7tbT3QCbvYjtBEpV",
      "duration_ms": 248696,
      "time_signature": 4
    },
    {
      "danceability": 0.702,
      "energy": 0.972,
      "key": 5,
      "loudness": -1.812,
      "mode": 0,
      "speechiness": 0.094,
      "acousticness": 0.686,
      "instrumentalness": 0,
      "liveness": 0.368,
      "valence": 0.739,
      "tempo": 133.034,
      "type": "audio_features",
      "id": "4gCKSBVrsOay3HYj5AvBq2",
      "uri": "spotify:track:4gCKSBVrsOay3HYj5AvBq2",
      "track_href": "https://api.spotify.com/v1/tracks/4gCKSBVrsOay3HYj5AvBq2",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/4gCKSBVrsOay3HYj5AvBq2",
      "duration_ms": 305853,
      "time_signature": 4
    },
    {
      "danceability": 0.692,
      "energy": 0.847,
      "key": 5,
      "loudness": -1.947,
      "mode": 0,
      "speechiness": 0.0534,
      "acousticness": 0.0238,
      "instrumentalness": 0,
      "liveness": 0.441,
      "valence": 0.712,
      "tempo": 132.053,
      "type": "audio_features",
      "id": "4pZA1GWGfG4JoZ0rbb8yG2",
      "uri": "spotify:track:4pZA1GWGfG4JoZ0rbb8yG2",
      "track_href": "https://api.spotify.com/v1/tracks/4pZA1GWGfG4JoZ0rbb8yG2",
      "analysis_url": "https://api.spotify.com/v1/audio-analysis/4pZA1GWGfG4JoZ0rbb8yG2",
      "duration_ms": 216147,
      "time_signature": 4
    }
  ]
}

という感じのデータがでてきました。


なんとなくの分析としますと…

現在上記の情報に相関関係があるのかどうかわかりません。
(楽曲キーや、BPMとかは近いんですよ。けどそれだけでは意味がない!)

いかがでしたか?

相関関係に関してはわかり次第随時追加していく予定です。ここまでご覧いただきありがとうございます。

次回予告:どうやって手持ちの楽曲をSpotifyAPIに投げるんだ……そしてそもそもの方向性はあっているのか……

CJM(カスタマージャーニーマップ)って作ったことある?

今日は通勤中にトンボを見たのでもう秋って感じですが、皆様いかがお過ごしですか?

KAI-YOU開発部わたはる(haruchan_jpg)です。

突然ですがwebサイトを作るときにどんな目的を持って作ってますか?

受託制作であればクライアントの好みに合わせることはもちろんですが、せっかくお金と時間をかけて作るならちゃんと効果があるもの、要するにwebサイトを見てくれる人に対して働きかけるものを作りたいですよね?

じゃあどのようにすればそのようなwebサイトを作れるか?

サイトを訪れるユーザーをよく知ることです。

CJM(カスタマージャーニーマップ)とは?

カスタマージャーニーマップ(以下、CJM)とは、ユーザーの体験プロセスを旅になぞって可視化するものです。

商品の購入やサービスへの加入、問い合わせなど、最終的なゴール設定をしそこに至るまでの各段階・時間軸に合わせてユーザーの感情、アプローチ方法をマップに整理していきます。

CJMを作ると何がいいのか?

  • ユーザーの行動を想像し、可視化しやすくなる
  • ユーザー目線の発想ができるようになる
  • マーケティングにおける意思決定が的確になる
  • 自分たちが規定したペルソナに対してチーム内で共有しやすくなる

早速CJM作ってみる?

それでは、早速CJMを作ってみましょう!

KAI-YOU.netはオールジャンルメディア、信じられないことに想定読者層は全人類というふざけた仕様です。(弊社代表談)

が!一応いわゆるユースカルチャーを中心にコンテンツを制作しています。

現在の実際の読者層はこのような感じになっています。

画像:読者層シート
KAI-YOU.netの読者層はこのような感じ

これをもとにペルソナシートを記入していきましょう。

実際にペルソナシートを記入してみました!

画像:ペルソナシート
森田くんへ。名前と写真をお借りしています。

ペルソナシートの項目ですが、細かければ細かいほどいいです。今回記入しているのは最低限といった感じですね。

※お名前とビジュアルイメージは弊社編集の森田くんからお借りしてますが、設定はまったく架空のものです。

初めてペルソナシートを作った時、え?名前やビジュアルイメージなんて必要?と思ったのですが、意外と重要なのです。

今回は私一人でペルソナシートを記入していますが、基本的にはチームで話し合って埋めていくのがベストです。

そしてチームで話し合う時に、名前とビジュアルイメージを共有しておくと「森田くんが〜」「森田くんだったら〜」みたいな友達にコンテンツを届けようって気持ちになれるんです。Webの向こう側にいる人を想像するのって難しいですが友達に見せるのだったらなんとなくその人の行動が読めると思います。

さて、次は実際にCJMを記入していきましょう。

CJMを記入してみました!

KAI-YOU.netは「腰を据えて読んでもらえるポップなWebメディア」を目指していますので、今回のコンバージョン設定は初めてKAI-YOU.netに訪れたユーザーに「ブックマークボタンを押させること」とします。初めてKAI-YOU.netに訪れた森田くんの行動を考えて定期的に訪れるリピーターになるまでのCJMを作ってみます。

画像:カスタマージャーニーマップ
森田くんがこんな風に動いてくれたらいいなという願望を詰め込む

なかなかざっくりした内容ですが森田くんがどんな状況で、どんなことを考えていて、どんなものを求めていて、どんな行動を起こすかを文字に起こしていきます。もちろんこういう風にスムーズに行動してくれたら嬉しいですが、なかなかこうはいかないのが現実です。

では、森田くんにこのような行動を起こさせられるかを考えるポイントを開発チームなりに書き出していきます。

  • ページスピードは遅くないか?
  • 特定の記事から他のコンテンツには遷移しやすいか?
  • 森田くんが押したくなるようなアイキャッチを選べているか?
  • 幅広いコンテンツを扱っていると見せられているか?
  • 定期的にトップページに訪れた時に森田くんにとってコンテンツを見つけやすい設計になっているか?

色々と反省点が見えてきますね。CJMは作って終わりでなく、できれば何度も見返してもしかしたら森田くんはこう思ってないかも、こういう行動をしないかもと考えるのも重要です。

まとめ

CJMを作り方をざっくり説明してきましたが、作って終わりじゃ意味がないのがCJMです。

チームで共有して、もしかしたらこう思ってないかもしれない、こういう行動はしないかもしれないと考え、常に改善していくのがベストです。また、Google Analyticsにイベントを設定し、数値と照らし合わせて考えていくのも大切ですね。

友達に届けるようにWebサイトの設計、運用をしていきましょう〜。

以上、わたはるでした。