{"id":21810,"date":"2018-10-31T19:25:19","date_gmt":"2018-10-31T19:25:19","guid":{"rendered":"http:\/\/building_a_music_discovery_service"},"modified":"2018-10-31T19:25:19","modified_gmt":"2018-10-31T19:25:19","slug":"building_a_music_discovery_service","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service","title":{"rendered":"Building a Music Player Application With Vue.js Framework"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>In May 2018, Cloudinary sponsored Capitol Music Group\u2019s first hackathon held by its new Capitol360 Innovation Center, which aims at connecting musicians and software technologists to facilitate and stimulate the creation of music. See this <a href=\"https:\/\/cloudinary.com\/blog\/capitol_music_group_on_making_new_music_with_tech\">interview<\/a> for details. As a starter project for the hackathon, we built a sample app called Music Discovery Service.<\/p>\n<hr \/>\n<p><strong>Due to licensing, we cannot display the app.<\/strong><\/p>\n<hr \/>\n<p>Building a Music Discovery Service brings together such technical concepts as consuming APIs, rendering audio in the browser, and transforming images. The Music Discovery Service combines them all as a music-player app in which you can browse through a list of artists, search for artists, pick an artist\u2019s album, view all the tracks in the selected album, and play songs from there.<\/p>\n<p>This guide walks you through the process of building a Music Discovery Service and highlights its key features.<\/p>\n<p>We built this app with the Vue.js JavaScript framework, ES6 JavaScript, and the Codepen environment. A working knowledge of their programming constructs would help you follow the process.<\/p>\n<h2>Components<\/h2>\n<p>This app contains four major components, each serving as a page for the component\u2019s content:<\/p>\n<ul>\n<li>\n<code>Browse<\/code> (also the home page)<\/li>\n<li>\n<code>BrowserList<\/code>\n<\/li>\n<li>\n<code>Album<\/code>\n<\/li>\n<li>\n<code>Playing<\/code>\n<\/li>\n<\/ul>\n<p>There are three support components:<\/p>\n<ul>\n<li>\n<code>RiseLoader<\/code>\n<\/li>\n<li>\n<code>Carousel<\/code>\n<\/li>\n<li>\n<code>AlbumList<\/code>\n<\/li>\n<\/ul>\n<h2>The Browse Component<\/h2>\n<p>Since the <code>Browse<\/code> page is also the home page; we must define its route such that those artists with names that start with a certain letter populate the page whenever someone visits the root route. In other words, define the routes for the <code>Browse<\/code> component to match that requirement. The route also redirects the visitor to the <code>\/browse\/a<\/code> route. That syntax means that the <code>browse<\/code> route takes a parameter, which is the letter of the alphabet, in this case <code>a<\/code>.<\/p>\n<h2>The BrowserList Component<\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-res.cloudinary.com\/image\/upload\/w_700,c_fill,f_auto,q_auto\/dpr_auto\/Discover_music_assets.png\" alt=\"Browser list\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1400\" height=\"982\"\/><\/p>\n<p>To display a list of the artists returned from the server, we need a <code>list<\/code> component for holding the individual data for the artists. That component also needs helper functions. To accomplish all that, we create a separate utility file and then import the file into the component.<\/p>\n<p>In the utility file, we declare and export the base API\u2019s URL for our project and the letters of the alphabet. The file contains a <code>goTo<\/code> function for navigation. Additionally, the file defines the query parameters for that particular route with the route name. The file also contains a <code>normalizeTitle<\/code> function that takes in a title string as a parameter, replacing all the spaces and forward slashes in <code>title<\/code> with <code>-<\/code>.<\/p>\n<p>Next, we feed data to the <code>BrowserList<\/code> component for display. How to get that data? From the API. Because we\u2019ve already defined the API with the <code>helper<\/code> function in the utility file, all we need to do is update the <code>Browser<\/code> component to make a request to the API and then feed that data to <code>BrowserList<\/code>.<\/p>\n<p>We now paginate the data returned from the server because we can\u2019t display everything on one page. Also, at this point, only the the artists whose first names start with the alphabet <code>a<\/code> are displayed. We must find a way to filter through the rest of the alphabet.<\/p>\n<p>Thankfully, Vuetify contains a pagination component, which, along with an alphabetic filter, we then add to the <code>Browsercomponent<\/code>.<\/p>\n<p>Also, in the <code>BrowserList<\/code> component, we add an event listener to listen for a page change and an alphabet filter.. For each letter, when a click event is triggered, the <code>goTo<\/code> method is called, which navigates the audience to the selected letter filter.<\/p>\n<p>Now we need a way to enable the audience to search for their favorite artist. You might say, \u201cOh if they know the artist\u2019s name, they can simply use the alphabet filter.\u201d Well, what if they don\u2019t? What if there were a hundred artists with the same name?<\/p>\n<p>Adding a search capability would greatly improve the app\u2019s user experience. We\u2019ve already added a search field to the UI. Now let\u2019s make it search for artists based on an entry.<\/p>\n<p>Next comes the addition of a carousel to the <code>Browse<\/code> page to showcase the imagery of the artists on the app. We create a separate component called <code>carousel.vue<\/code> to handle the functionality of the carousel and then place the component in the <code>Browse<\/code> page, as follows:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>\/\/carous.vue\n....\nmethods: {\n  transformCoverImage(item) {\n    console.log(item);\n    let url =\n      item.image ||\n      'http:\/\/artwork-cdn.7static.com\/static\/img\/artistimages\/00\/008\/194\/0000819457_300.jpg';\n    return this.cl.url(url, {\n      width: '1036',\n      height: 250,\n      gravity: 'center',\n      crop: 'pad',\n      aspectRatio: '16:9',\n      background: 'auto:predominant',\n      effect: 'gradient_fade:symmetric_pad:0.05',\n      fetchFormat: 'auto',\n      format: 'png',\n      quality: 'auto',\n      type: 'fetch',\n    });\n  },\n  ....\n<\/code><\/pre>\n<p>The <code>cl<\/code> function we imported from the utility file is from the Cloudinary library. With Cloudinary, the media-management platform for web and mobile developers, we can transform the images on the carousel as seen in the <code>transformCoverImage<\/code> method. .<\/p>\n<p>So, let\u2019s install the Cloudinary JavaScript library for image transformation. Run the following command in a terminal in your project folder:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>npm install cloudinary-core\n<\/code><\/pre>\n<p>Afterwards, open the utility file and initialize the Cloudinary library there with the snippet below:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>\/\/ utils.js\n...\nexport const cl = cloudinary.Cloudinary.new({\n  cloud_name: 'christekh',\n  secure: true,\n});\n<\/code><\/pre>\n<p>Finally, reference the newly-created carousel component on the <code>Browse<\/code> page. That component is displayed right above the search field.<\/p>\n<h2>The Album Component<\/h2>\n<p>When the audience clicks an artist name on the <code>Browse<\/code> page, they\u2019d expect to see a list of the artist\u2019s featured albums. For that to happen, we create a separate component that serves as the album page. We then click an artist name on the <code>Browse<\/code> page to see what should be on that album list. For now, only breadcrumbs are displayed; let\u2019s generate an album list.<\/p>\n<p>Before making the call to the server for a list of an artist\u2019s albums, we need a component to display that list. For that purpose, we create a component called <code>AlbumList<\/code>, which we loop through and then display the list of items as a component property. <code>AlbumList<\/code> receives two properties:<\/p>\n<p><code>items<\/code>, the list of albums\n<code>cl<\/code>, the Cloudinary library for image transformation<\/p>\n<p>The album list is now all set, showing the albums on the <code>Album<\/code> page. As a nice touch, show the artist\u2019s image on the <code>Album<\/code> page.<\/p>\n<h2>Music Player<\/h2>\n<p>Finally, we build a page on which the songs in the album are played on demand We do that by creating a component called <code>Player<\/code>, which handles the listing of tracks on an album and which also holds the player. That player is a component that controls the music the audience will be listening to: play, stop, shuffle, and so forth.<\/p>\n<p>Here\u2019s what we do: Create a file called <code>Player.vue<\/code> with the following snippet in the components folder:<\/p>\n<pre class=\"js-syntax-highlighted\"><code>....\ntransformAlbumAvatarImage() {\n  return this.cl.url(this.album.image, {\n    width: 200,\n    height: 200,\n    gravity: 'auto',\n    crop: 'fill',\n    fetchFormat: 'auto',\n    quality: 'auto',\n    type: 'fetch',\n  });\n},\ntransformArtistBannerImage() {\n  return this.cl.url(this.artist.image, {\n    width: 1800,\n    height: 150,\n    gravity: 'west',\n    crop: 'lpad',\n    aspectRatio: '16:9',\n    background: 'auto:predominant',\n    fetchFormat: 'auto',\n    quality: 'auto',\n    type: 'fetch',\n  });\n},\n....\n<\/code><\/pre>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>We used Cloudinary to transform the banner images in the <code>transformAlbumAvatarImage<\/code> and <code>transformArtistBannerImage<\/code> methods.<\/p><\/div>\n<p>Next, we update the player component to fetch the tracks from the server.<\/p>\n<h2>Playing of the Music<\/h2>\n<p>Even though the <code>Player<\/code> page is now done, we have yet to play any music there. To set up a player on the page, we leverage the <a href=\"https:\/\/github.com\/SevenOutman\/vue-aplayer\"><code>vue-aplayer<\/code><\/a> library, which contains a <code>player<\/code> component with controls for play, stop, shuffle, forward, and other tasks. To make use of <code>player<\/code>, we load the album\u2019s track list on it and then update the <code>Player.vue<\/code> file.<\/p>\n<h2>Social Sharing<\/h2>\n<p>A neat feature would be to enable the audience to share the track they are listening to. The <a href=\"https:\/\/github.com\/nicolasbeauvais\/vue-social-sharing\">vue-social-sharing<\/a> library makes creating social-sharing links a breeze. Simply feed the information about the current playing track into the component and it will generate a sharing link.<\/p>\n<p>Two steps are involved:<\/p>\n<p>Register the social-sharing library as an external plugin for the app.\nOpen the <code>Player.vue<\/code> file and update it to include the social-sharing links for the player.<\/p>\n<p>That\u2019s it. Simple as ABC.<\/p>\n<h2>Conclusion<\/h2>\n<p>You\u2019ve just learned how to build a music player with VueJs. In the process, you\u2019re acquainted with concepts like image transformations with Cloudinary, fetching and displaying data from an API, and making use of external plugins. Let us know if you have any questions in comments.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":21811,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[25,28,165,177,315],"class_list":["post-21810","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-asset-management","tag-audio-transformation","tag-image-transformation","tag-javascript","tag-vue"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Building a Music Player Application With Vue.js Framework<\/title>\n<meta name=\"description\" content=\"Learn how to build a music player application with Cloudinary and Vue.js.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a Music Player Application With Vue.js Framework\" \/>\n<meta property=\"og:description\" content=\"Learn how to build a music player application with Cloudinary and Vue.js.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-10-31T19:25:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1540\" \/>\n\t<meta property=\"og:image:height\" content=\"847\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Building a Music Player Application With Vue.js Framework\",\"datePublished\":\"2018-10-31T19:25:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service\"},\"wordCount\":9,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA\",\"keywords\":[\"Asset Management\",\"Audio Transformation\",\"Image Transformation\",\"Javascript\",\"Vue\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2018\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service\",\"url\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service\",\"name\":\"Building a Music Player Application With Vue.js Framework\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA\",\"datePublished\":\"2018-10-31T19:25:19+00:00\",\"description\":\"Learn how to build a music player application with Cloudinary and Vue.js.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA\",\"width\":1540,\"height\":847},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a Music Player Application With Vue.js Framework\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Building a Music Player Application With Vue.js Framework","description":"Learn how to build a music player application with Cloudinary and Vue.js.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service","og_locale":"en_US","og_type":"article","og_title":"Building a Music Player Application With Vue.js Framework","og_description":"Learn how to build a music player application with Cloudinary and Vue.js.","og_url":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service","og_site_name":"Cloudinary Blog","article_published_time":"2018-10-31T19:25:19+00:00","og_image":[{"width":1540,"height":847,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service"},"author":{"name":"","@id":""},"headline":"Building a Music Player Application With Vue.js Framework","datePublished":"2018-10-31T19:25:19+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service"},"wordCount":9,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA","keywords":["Asset Management","Audio Transformation","Image Transformation","Javascript","Vue"],"inLanguage":"en-US","copyrightYear":"2018","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service","url":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service","name":"Building a Music Player Application With Vue.js Framework","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA","datePublished":"2018-10-31T19:25:19+00:00","description":"Learn how to build a music player application with Cloudinary and Vue.js.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA","width":1540,"height":847},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/building_a_music_discovery_service#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Building a Music Player Application With Vue.js Framework"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649721652\/Web_Assets\/blog\/Building-a-Music-Discovery-Service\/Building-a-Music-Discovery-Service.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21810","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=21810"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/21810\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/21811"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=21810"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=21810"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=21810"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}