Upgrade to Pro — share decks privately, control downloads, hide ads and more …

音楽の未来 〜スマートスピーカーとAWAがオトモダチになるまで〜 / Smartspeaker...

CyberAgent
February 22, 2019

音楽の未来 〜スマートスピーカーとAWAがオトモダチになるまで〜 / Smartspeaker_AWA

サイバーエージェントの技術者(エンジニア・クリエイター)向けカンファレンス『CA BASE CAMP 2019』

音楽の未来 〜スマートスピーカーとAWAがオトモダチになるまで〜
北原 有貴

CyberAgent

February 22, 2019
Tweet

More Decks by CyberAgent

Other Decks in Technology

Transcript

  1. 1.εϚʔτεϐʔΧʔࢢ৔ͷՄೳੑ !14 3rdύʔςΟ͔ΒAIΞγελϯτ౥ࡌεϐʔΧʔ͕ଓʑొ৔ LF-S50G WC / SONY Google Assistant Amazon

    Alexa VCGX30B / ONKYO ALLUE / Harman Kardon HOME SPEAKER 500 / BOSE LS mini / LiveSmart Sonos One / Sonos ྆ํ౥ࡌ ※ରԠ༧ఆ
  2. 1.εϚʔτεϐʔΧʔࢢ৔ͷՄೳੑ • ถࠃͰτϤλ/LexusͷҰ෦ंछʹAlexa౥ࡌ • Alexa Auto SDK Λൃද • 12݄

    Fire TV Stick͕AlexaରԠ !15 2018೥ Alexaͷंࡌ౥ࡌɾεϚʔτTV౥ࡌ͕Ճ଎ εϐʔΧʔͷීٴʹ͔͔ΘΒͣ
 AIΞγελϯτʹରԠ͢Ε͹
 Մೳੑ͕޿͕Δ
  3. 2.ԻָαʔϏεͱͷ૬ੑͷྑ͞ !17 εϚʔτεϐʔΧʔอ༗ऀ͸༗ྉϓϥϯʹੵۃత Amazon Music × Echo΍ LINE Music ×

    ClovaͷΑ͏ʹɺ ҆Ձͳϓϥϯ΍௕ظͷແྉظؒͱͷ ηοτൢച΋ଟ͘ɺॳΊͯαϒεΫ ϦϓγϣϯΛମݧ͢ΔϢʔβ΋ଟ͍ Իָ഑৴αϒεΫͷʮεϚʔτεϐʔΧʔʯ࢖༻ͷ࣮ଶ ΑΓҾ༻ https://amp.review/2018/03/30/smartspeaker/
  4. ࠷΋࢖͍ͨ͘ͳΔԻָϓϩόΠμΛ໨ࢦͯ͠ !21 • ແྉΞΧ΢ϯτͰ΋࢖͑Δ • ࣭ͷྑ͍ϓϨΠϦετ͕બग़͞ΕΔΑ͏ʹ • ΦϯσϚϯυ࠶ੜ͕Ͱ͖Δ • ࣗ෼͕࡞੒ͨ͠ϓϨΠϦετ͕࠶ੜͰ͖Δ

    • ΞϓϦͰ͓ؾʹೖΓͨ͠ۂ͕࠶ੜͰ͖Δ • ύʔιφϥΠζ͞ΕͨDiscovery͕࠶ੜͰ͖Δ ඞਢػೳϓϥεΞϧϑΝΛ࣮ݱͯ͠AWA඼࣭Λ໨ࢦ͢
  5. Google Home / Google Backendͷ࢓ࣄ !23  ϢʔβͷϘΠεΛ#BDLFOE΁
 ૹ৴ 

    ϘΠεΫΤϦΛࣗવݴޠॲཧͯ͠
 ݕࡧΫΤϦʹม׵  Ϣʔβઃఆ΍ΧλϩάΛݕࡧ  ্Ґ݁ՌΛूܭ  ݁ՌΛݩʹىಈαʔϏεΛબ୒  BDDFTTUPLFOͱEFFQMJOLΛ
 Ϩγʔόʔ )PNF ʹૹ৴ Google Home Google Backend  554ͰϢʔβʹϑΟʔυόοΫ  "8"ϨγʔόʔىಈɾಡΈࠐΈ
  6. 2. Receiver !29 (PPHMF)PNF͕࠶ੜཁٻɾΩϡʔૢ࡞͢ΔͨΊͷϓϩάϥϜ • Ξοϓϩʔυ͞Εͨ։ൃίʔυΛGoogle Home͕μ΢ϯϩʔυͯ͠ར༻ • OAuthͰϢʔβʔ͕ঝೝ͞ΕΔͱɺGoogle Home͸ͦΕҎ߱ͷશͯͷ࠶ੜ


    ϦΫΤετʹOAuthΞΫηετʔΫϯΛૹ৴ • Ϩγʔόʔ͸ͦͷτʔΫϯͰAWA API͔Βύʔιφϧ৘ใΛऔಘͨ͠Γɺ
 ࠶ੜΩϡʔΛߏஙͨ͠ΓɺϝσΟΞίϯτϩʔϧΛߦ͏
  7. AWAͰ͸ϦϦʔεࡁͷGoogle Castίʔυͱڞ༻ !31 1. JavaScriptͰهड़͍ͯͨ͠ίʔυΛTypeScript + React / Redux ʹ

    ͜Ε·ͰɿεϚϗ͔ΒͷϦΫΤετͰ࠶ੜ Sender:εϚϗ -> Receiver:Google Cast ϦϦʔεޙɿGoogle Assistant͔Β΋࠶ੜͰ͖ΔΑ͏ʹ Sender:Google Assistant(Home) -> Receiver:Google Home ͭ·Γ"TTJTUBOU͕౥ࡌ͞Ε͍ͯΕ͹4FOEFSʹͳΕΔ 2. Home͸Sender, Receiver྆ํඋ͓͑ͯΓ1୆Ͱ׬݁Ͱ͖ΔΑ͏ʹ
  8. 3. Data Feeds !33 (PPHMF$MPVEͷݕࡧͱ"8"ͷίϯςϯπΛϚονͤ͞Δ • ͦͷͨΊʹGoogleʹAWAͷίϯςϯπͷϝλ৘ใΛఏڙ͢Δ • Google͸ͦΕΛSearchΤϯδϯʹऔΓࠐΜͩΓAssistantͷֶशʹ࢖͏
 →

    Feed Ingestion ͱ͍͏ • Feed format͸JSON-LD • Feedʹ͸࠶ੜՄೳͳdeeplink(URL)͕ೖΓɺGoogle Cloud͸ͦͷdeeplink Λloadؔ਺ͰAWAͷReceiverʹ౉͢
  9. { "@context": "http://schema.org", "@type": "DataFeed", "dateModified": "2019-02-22T15:11:32+09:00", "dataFeedElement": [ {

    "@context": "http://schema.googleapis.com/", "@type": "MusicRecording", "@id": "https://s.awa.fm/track/trackId1", "name": "trackName1", "url": "https://s.awa.fm/track/trackId1", "popularityScore": [ { "@type": "PopularityScoreSpecification", "value": 1, Feed Spec for Media Actions ͋Δtrackͷྫ @id: ҰҙͰ͋Ε͹ԿͰ΋Α͍
  10. “byArtist": { "@type": "MusicGroup", "@id": "https://s.awa.fm/artist/artistId1", "name": "artistName1" }, "inAlbum":

    { "@type": "MusicAlbum", "@id": "https://s.awa.fm/album/albumId1", "name": "albumName1" }, "duration": "PT5m11s", "publisher": "גࣜձࣾA", "thumbnailUrl": "https://pimg.awa.io/v2/jacket/albumId1.h600.w600.jpg", "potentialAction": [ { Feed Spec for Media Actions ͋Δtrackͷྫ
  11. "potentialAction": [ { "@type": "ListenAction", "target": [ { "@type": "EntryPoint",

    "urlTemplate": "https://s.awa.fm/track/trackId1? action=play&play_type=google_assistant", "actionPlatform": [ "http://schema.org/DesktopWebPlatform", "http://schema.org/MobileWebPlatform", "http://schema.org/IOSPlatform", "http://schema.org/AndroidPlatform", "http://schema.googleapis.com/GoogleAudioCast", "http://schema.googleapis.com/GoogleVideoCast" ] Feed Spec for Media Actions ͋Δtrackͷྫ actionPlatform: ࠶ੜΛڐՄ͢ΔPlatform urlTemplate: Ϩγʔόʔ͕ίϯςϯπΛղऍ ͢ΔͨΊͷURL
  12. "expectsAcceptanceOf": { "@type": "Offer", "eligibleRegion": [ { "@type": "Country", "name":

    "JP" } ], "category": "subscription", } } ] }, … ] Feed Spec for Media Actions ͋Δtrackͷྫ ͜ͷΦϒδΣΫτͷ͔ͨ·Γ͕1ϑΝΠϧ50MB΄Ͳʹऩ·Δ·Ͱଓ͍͍ͯ͘
  13. Feed Spec for Media Actions !38 ͜ΕΛ1೔1ճશίϯςϯπੜ੒ͯ͠Googleʹఏڙ • τϥοΫ2017೥౰࣌໿4,000ສ →

    ݱࡏ͸5,000ສҎ্ • ΞϧόϜ໿500ສ • ΞʔςΟετ໿350ສ • ࢼ͠ʹੜ੒ͨ͠1ϑΝΠϧͷॲཧ͔࣌ؒΒɺ୯७ܭࢉͨ͠ΒτϥοΫ͚ͩͰ120࣌ ؒҎ্͔͔Δ →ੜ੒ϓϩάϥϜͷޮ཰Խ͕ඞਢཁ݅
  14. ϫʔΧʔʹ͍ͭͯ(1/2) !40 ϫʔΧʔ͸InterfaceͰఆٛͯ͠ɺtrack / album / artist / playlistͷ֤struct͕
 ͦΕΒΛ࣮૷͍ͯ͘͜͠ͱͰɺجຊతͳੜ੒ϧʔτΛڞ௨Խͤ͞Δ

    Worker interface { SetEntity(entity interface{}) IsTarget() bool FetchFavorite() (fav int, err error) SetRelatedContents() (contents map[string]string, err error) EncryptIDs() map[string]string EscapeNames(contents map[string]string) map[string]string CreateElement(fav int, encIDs, escapeNames map[string]string) (bytes.Buffer, error) }
  15. ϫʔΧʔʹ͍ͭͯ(2/2) !41 ϫʔΧʔͷॲཧͰ΋I/OΠϕϯτ΍ฒߦॲཧ͕Մೳͳ෦෼͸ੵۃతʹฒྻԽ͠ɺ sync.WaitGroupͰॲཧΛ଴ͪ߹ΘͤΔ … wg := &sync.WaitGroup{} wg.Add(3) var

    params feedParams go fetchFavorite(w, wg, &params) go fetchRelatedContents(w, wg, &params) go encryptIDs(w, wg, &params) wg.Wait() … func fetchFavorite(w Worker, wg *sync.WaitGroup, params *feedParams) { defer wg.Done() fav, err := w.FetchFavorite() params.fav = fav if err != nil { params.err = multierror.Append(params.err, errors.Wrap(err, "failed to FetchFavorite")) } }
  16. νϡʔχϯά͠΍͍͢Α͏ʹ !42 ࠶Ϗϧυ͢Δ͜ͱͳ͘ઃఆ஋Λ͍͡ΕΔΑ͏؀ڥม਺Λଟ༻ type configuration struct { MongoHost string `envconfig:"MONGO_HOST"

    default:"localhost:27017"` MongoDatabase string `envconfig:"MONGO_DATABASE" default:"test"` MongoSocketTimeout int `envconfig:"MONGO_SOCKET_TIMEOUT" default:"15"` RedisAddr string `envconfig:"REDIS_ADDR" default:"localhost:6379"` RedisDB int `envconfig:"REDIS_DB" default:"0"` Mode string `envconfig:"MODE" default:"test"` Type string `envconfig:"TYPE"` WorkerNum int `envconfig:"WORKER_NUM" default:"10"` Timeout int `envconfig:"TIMEOUT" default:"300"` FindLimit int `envconfig:"FIND_LIMIT" default:"500000"` FeedLimit int `envconfig:"FEED_LIMIT" default:"50000"` } • WorkerNum: ϫʔΧʔ਺ • FindLimit: DB͔ΒҰ౓ʹ औಘ͢Δ਺ • FeedLimit: 1ϑΝΠϧʹ
 ੜ੒͢Δίϯςϯπ਺ ݱࡏ͸τϥοΫ5,000ສʹରͯ͠35ʙ40෼ఔͰऴΘΔΑ͏ʹ
  17. AWA SideɿϑΟʔυੜ੒ɾAPIશମߏ੒ਤ !45 Route 53 API Gateway S3 Bucket AWS

    Cloud VPC ECR AWS Batch Lambda event (time-base) ECS CloudWatch AWA API CloudFront for feeds creation Requests from Partner ໊લղܾ Internet όονίʔυ S3 Bucket Lambda functionίʔυ GitHub EC2 (Build Server) git push git push External API
  18. 4. External API 1. Route 53Ͱఆٛͨ͠CNAMEϨίʔυΛCloudFrontͷCNAMEsʹηοτ 2. CloudFrontͷOrigin NameʹAPI Gatewayͷ”Endpoint/Stage”Λࢦఆ

    3. CloudFront͸SSLऴ୺ͱɺ΋͠΋ͷͨΊʹΩϟογϡ͢Δ໨తͰ४උ 4. Lambda function͸GolangͰ࣮૷͠ɺϏϧυόΠφϦΛΞοϓϩʔυ 5. API GatewayͱLambdaͦΕͧΕ͔ΒARNΛඥ෇͚Δ Route 53 API Gateway Lambda ECS AWA API CloudFront Requests from Partner ໊લղܾ Internet Lambda !46 upload
  19. AWS BatchͰಠཱͨ͠؀ڥͰ࣮ߦ͢ΔΑ͏ʹ S3 Bucket VPC ECR AWS Batch event (time-base)

    CloudWatch όονίʔυ S3 Bucket EC2 (Build Server) git push • ϑϧϚωʔδυܕͷόονίϯϐϡʔςΟϯάδϣϒͷ࣮ߦ؀ڥ ECS EC2 Cluster Docker Image auto scaling Feeds git pull pull image download shell & binary build binary Job Definition
  20. AWS BatchͰಠཱͨ͠؀ڥͰ࣮ߦ͢ΔΑ͏ʹ S3 Bucket VPC ECR AWS Batch event (time-base)

    CloudWatch όονίʔυ S3 Bucket EC2 (Build Server) git push ECS EC2 Cluster Docker Image auto scaling Feeds git pull pull image download shell & binary build binary ᶃ CPU Unit΍ϩʔϧ౳Λఆٛͨ͠ίϯϐϡʔςΟϯά؀ڥ(EC2)Λ࡞੒ ᶄ ্ه؀ڥΛར༻͢ΔδϣϒΛఆٛɻϝϞϦ΍؀ڥม਺͸͜͜Ͱࢦఆ͢Δɻ Job Definition ᶃ ᶄ !54
  21. AWS BatchͰಠཱͨ͠؀ڥͰ࣮ߦ͢ΔΑ͏ʹ ᶅ CloudWatchΠϕϯτΛcronͰεέδϡʔϦϯά͠ɺλʔήοτʹ
 AWS BatchδϣϒΛࢦఆ S3 Bucket VPC ECR

    όονίʔυ S3 Bucket EC2 (Build Server) git push EC2 Cluster Docker Image auto scaling Feeds git pull pull image download shell & binary build binary Job Definition AWS Batch event (time-base) CloudWatch ᶅ !55 ECS
  22. AWS BatchͰಠཱͨ͠؀ڥͰ࣮ߦ͢ΔΑ͏ʹ ᶆ ॲཧίʔυΛϏϧυͨ͠GoόΠφϦΛS3 Bucketʹ഑ஔ ᶇ ্هόΠφϦΛS3͔Βऔಘ࣮ͯ͠ߦ͢ΔDockerΠϝʔδΛECRʹ४උ
 →ࣗಈతʹߏங͞ΕΔECSΫϥελɾαʔϏε(EC2λΠϓ)্Ͱ࣮ߦ͞ΕΔͨΊ S3 Bucket

    VPC AWS Batch event (time-base) CloudWatch ECS EC2 Cluster auto scaling Feeds pull image download shell & binary Job Definition !56 ECR όονίʔυ S3 Bucket EC2 (Build Server) git push git pull build binary Docker Image ᶆ ᶇ
  23. AWS BatchͰಠཱͨ͠؀ڥͰ࣮ߦ͢ΔΑ͏ʹ !57 δϣϒ͕αϒϛοτ͞ΕͨΒΩϡʔʹཷ·ΓEC2 Cluster͕ߏங͞ΕΔɻ Cluster্ͰECSλεΫ͕γΣϧΛμ΢ϯϩʔυɾΩοΫ͠ɺGoόΠφϦ Λμ΢ϯϩʔυɾ࣮ߦͯ͠ϑΟʔυ࡞੒ɾS3ʹΞοϓϩʔυ·Ͱߦ͏ɻ S3 Bucket VPC

    ECR AWS Batch event (time-base) CloudWatch όονίʔυ S3 Bucket EC2 (Build Server) git push ECS EC2 Cluster Docker Image auto scaling Submit Job Add a queue to Job Feeds git pull pull image download shell & binary build binary Job Definition
  24. AWS BatchͰ՝୊ʹײͨ͡఺ w ࠷ॳͷ؀ڥ४උ͕΍΍खؒ w ීஈ࢖͍͸+FOLJOTͳͲͷ$*$%πʔϧͰ0, w ࠓճͷΑ͏ͳ՝୊Λղܾ͚ͨ͠Ε͹ w ։࢝࣌ؒʹݫີͳόονॲཧʹ͸ෆ޲͖

    w &$ͳͲͷϦιʔε४උ͕ඞཁͳͱ͖͸։͕࢝஗͘ͳΔ w δϣϒͷ࣮ߦॱংΛ੍ޚ͢Δʹ͸4UFQ'VODUJPOTͳͲͷ ػೳΛซ༻͢Δඞཁ͋Γ ݱࡏ ͱ͸͍͑ৗ࣌Քಇ͍ͯ͠ΔόονΠϯελϯεͷϦιʔεʹׯব ͠ͳ͍͠ɺ͏·͘࢖͑͹ίετతʹ΋͓͢͢Ί !58
  25. Popularity ScoreΛಋೖ !61 • ࠶ੜ΍͓ؾʹೖΓ࣮੷͕͋ΔίϯςϯπͷείΞΛܭࢉͯ͠HIT͠΍͘͢ • શείΞ͸1೔1ճϑΟʔυ࡞੒લʹߋ৽ 127.0.0.1:6379> scan 0

    1) “soon:track" 2) "topic:track" 3) "general:track" 4) "topic:album" 5) "general:album" 6) "topic:artist" 7) “general:artist" soon:[type] -> ϦϦʔεલͷίϯςϯπ topic:[type] -> ϦϦʔε͔ΒҰఆظؒͷίϯςϯπ general:[type] -> ্هҎ֎ͷ࠶ੜ࣮੷͕͋Δίϯςϯπ
  26. ਓؾͷۂ͕HIT͠΍͘͢ͳͬͨ !62 Redisͷ֤ΫϥελϝϯόʔΛಡΈࠐΈɺ࠶ੜ࣮੷ͷ͋Δ ίϯςϯπΛλʔήοτʹϑΟʔυੜ੒ 127.0.0.1:6379> zrevrange general:track 0 2 withscores

    1) "trackId001" 2) “13935530" 3) "trackId003" 4) "12261936" 5) "trackId002" 6) "9867839" τϥοΫ࠶ੜ࣮੷Ϋϥελͷ্Ґ3ۂΛදࣔ ࠶ੜɾ͓ؾʹೖΓɾϓϨΠϦετ࠾༻਺ΛՃຯͨ͠είΞ
  27. !66 • τϥοΫ / ΞϧόϜ / ΞʔςΟετ / ϓϨΠϦετ /

    ϢʔβผͷWebϖʔδ • ֤ίϯςϯπΛࢼௌ࠶ੜͰ͖Δ • AWAͷೝ஌ɾΞϓϦ΁ͷτϥϑΟοΫͱͯ͠ॏཁ AWAͷγΣΞϖʔδͱ͸ʁ
  28. !68 • ࠷େϗετɿ8 → 20 • ΠϯελϯελΠϓɿt2.small → c4.xlarge •

    CPU༻ͷCloudWatchΞϥʔϜɿaverage → maximumʹɻ͖͍͠஋΋60 → 40ʹͯ͠ɺݕ஌࣌ʹ2ίϯςφͣͭ૿͑ΔΑ͏ʹ • ΠϝʔδαΠζ΋ݮΒͯ͠ૉૣ͘ίϯςφىಈͰ͖ΔΑ͏ʹ ௚ۙEC2→ECSʹߏ੒มߋ͠ɺίϯςφϗετͷCPU Unit͕ ෛՙʹରͯ͠଍Γͣʹόʔετͨ͜͠ͱ͕ݪҼ →1୆ʹ4ίϯςφɺ࠷େಉ࣌ʹ80ίϯςφىಈ͢Δܭࢉ ରࡦɿΞϥʔϜɾΦʔτεέʔϧͷݟ௚͠
  29. !75 w 8"' 8FC"QQMJDBUJPO'JSFXBMM  w ࠷খઃఆͷ SFRNJOͰݕূ w ϒϩοΫ͞Εͣɻӈ͸શͯͷϦΫΤετ

    ͕ڐ༰͞Ε͍ͯΔάϥϑ AWS WAFͷϨʔτϕʔεϧʔϧͰ΋ࢭ·Βͳ͍ʂ Ϋϩʔϥ͔ΒͷϦΫΤετ͸Ұ෦IP͸ॏෳ͍ͯ͠Δ΋ͷͷɺ͔ͳΓ ͷ୆਺͔Β෼ࢄ͍ͯ͠Δ
  30. AWAͱGoogle Home͸ΦτϞμνʹ !78  EJTDPWFSZ Կ͔࠶ੜԻָΛ࠶ੜͷτϦΨʔ   ΫϦεϚεϓϨΠϦετ 

    64"  உͷ܄ষ  58*$&  %"16.1  26&&/  .S$IJMESFO  ͍͋ΈΐΜ ੢໺Χφ 2018/12/20ʙ27ͷ࠶ੜϥϯΩϯά ݱࡏͷΦτϞμν౓ɿ100 %
  31. ൓ল఺ͱ՝୊(2/3) !81 • (Google) ೔ຊޠͷԻ੠ೝࣝͷ೉͠͞ • γνϡΤʔγϣϯ࠶ੜʹ͓͍ͯɺ೿ੜχϡΞϯε͕ղऍ͞Εͳ͔ͬͨ • ྫ͑͹ “य़”ɺ”य़ͷۂ”ɺ”य़ʹௌ͖͍ͨۂ”

    ͳͲͷࡉ͔͍ҧ͍Ͱ΋શͯ
 όϦΤʔγϣϯͱͯ͠ϑΟʔυఏڙͨ͠ํ͕HIT͠΍͘͢ͳͬͨ • “AWA” ͸։ൃऴ൫·Ͱ “ΤʔɾμϒϦϡʔɾΤʔ” ͱൃԻ͞Ε͍ͯͨ • ݪҼ͸ΞϝϦΧͷϓϩϨεஂମ • ݱࡏ͸গ͠վળͯ͠ “Ѩ೾㽉” ͱൃ࿩͞ΕΔɾɾ(´ʀωʀʆ)