{"id":2837,"date":"2017-07-08T04:45:45","date_gmt":"2017-07-08T04:45:45","guid":{"rendered":"http:\/\/truelogic.org\/wordpress\/?p=2837"},"modified":"2017-07-08T04:45:45","modified_gmt":"2017-07-08T04:45:45","slug":"15-youtube-data-api-channel-banners","status":"publish","type":"post","link":"https:\/\/truelogic.org\/wordpress\/2017\/07\/08\/15-youtube-data-api-channel-banners\/","title":{"rendered":"15 &#8211; YouTube Data API &#8211; Channel Banners"},"content":{"rendered":"            <script type=\"text\/javascript\" src=\"https:\/\/truelogic.org\/wordpress\/wp-content\/plugins\/wordpress-code-snippet\/scripts\/shBrushPhp.js\"><\/script>\n<p style=\"text-align: center;\"><strong>This is article 15 of the YouTube API With PHP series.<\/strong><\/p>\n<p>A Channel Banner is the image which shows up the Channel homepage in the page header. You can only set one image for a banner. This API resource has only one function available.<\/p>\n<p><strong>1.insert<\/strong><\/p>\n<p><strong>\u00a0<\/strong>This API function will upload an image and assign it as the Channel banner image. The following restrictions apply:<\/p>\n<ul>\n<li>The image has to be a valid jpg pr png.<\/li>\n<li>It should have a minimum size of 2048&#215;1152 pixels. Ideally it should be 2560px by 1440px .<\/li>\n<li>It should have an aspect ratio of 16:9<\/li>\n<li>It cannot exceed 6 Mb in filesize.<\/li>\n<\/ul>\n<p>Updating an image as the Channel Banner requires two API calls:<\/p>\n<ol>\n<li>The first API call channelBanner.insert will upload the image. A successful upload will return the URL of the uploaded image.<\/li>\n<li>This URL will then have to be updated in the Channel by calling the channel.update API call.<\/li>\n<\/ol>\n<p>This API requires user authentication so you can only update the banner of your own channel. The access token is passed in the request header and not as part of the request URL.<\/p>\n<p>The Request URLs are<\/p>\n<pre><span style=\"color: #999999;\">POST https:\/\/www.googleapis.com\/upload\/youtube\/v3\/channelBanners\/insert<\/span>\r\n\r\n<span style=\"color: #999999;\">PUT https:\/\/www.googleapis.com\/youtube\/v3\/channels<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Parameters:<br \/>\n<\/strong><\/p>\n<ul>\n<li><strong>key<\/strong> (string) required. Your API key<\/li>\n<li><strong>onBehalfOfContentOwner<\/strong> (string) optional. This is relevant only for YouTube Channel Partners. For this parameter, the API request URL should have user authentication.We will not be exploring this option.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p><strong>Example Requests<\/strong><\/p>\n<p>Update the channel banner of the current authenticated user<\/p>\n<pre><span style=\"color: #999999;\">https:\/\/www.googleapis.com\/upload\/youtube\/v3\/channelBanners\/insert?key=xxxx<\/span>\r\n<span style=\"color: #999999;\">https:\/\/www.googleapis.com\/youtube\/v3\/channels?part=brandingSettings&amp;key=xxx&amp;access_token=xxx<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Response<\/strong><\/p>\n<p><strong>\u00a0<\/strong>A successful request will return a json encoded ChannelBanner resource which is shown below.<\/p>\n<pre><span style=\"color: #999999;\"><em>\u00a0<\/em>{<\/span>\r\n<span style=\"color: #999999;\">\u00a0 \"kind\": \"youtube#channelBannerResource\",<\/span>\r\n<span style=\"color: #999999;\">\u00a0 \"etag\": etag,<\/span>\r\n<span style=\"color: #999999;\">\u00a0 \"url\": string<\/span>\r\n<span style=\"color: #999999;\">}<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>The Response components are explained below:<\/p>\n<ul>\n<li><strong>kind<\/strong> (string) \u201cyoutube#<em>channelBannerResource<\/em>.\u201d<\/li>\n<li><strong>etag<\/strong> (string) See ETags Explained section<\/li>\n<li><strong>url<\/strong> (string) url of the banner image<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Sample code to update the channel banner:<\/p>\n<p><pre class=\"brush: php\">&lt;?php\r\n    error_reporting(E_ALL ^ E_NOTICE ^ E_WARNING ^ E_DEPRECATED);\r\n    set_time_limit(60 * 3);\r\n    session_start();\r\n\r\n    $clientId = &quot;***&quot;;\r\n    $clientSecret = &quot;**&quot;;\r\n    $g_youtubeDataAPIKey = &quot;**&quot;;\r\n\r\n    $channelId =  &quot;UCnXmfpAZ1rLsg0Goh0bBHUA&quot;;\r\n    \r\n    $_SESSION[&quot;code_id&quot;] = $_SERVER[&quot;PHP_SELF&quot;];\r\n    \r\n    if ($_SESSION[&quot;access_token&quot;] == null || $_SESSION[&quot;access_token&quot;] == &quot;&quot;) {\r\n   \t \/\/ check for oauth response\r\n   \t header(&quot;Location: ..\/..\/init-login.php&quot;);\r\n   \t exit;\r\n    }\r\n\r\n   \t $accessToken = $_SESSION[&quot;access_token&quot;];\r\n\r\n   \t \/\/ load image file contents\r\n   \t $fh = fopen(&quot;channelbanner.png&quot;, &quot;r&quot;);\r\n   \t if (!$fh)\r\n   \t\t exit(&quot;Could not open image file &quot;);\r\n   \t fclose($fh);\r\n   \t $fileData = file_get_contents(&quot;channelbanner.png&quot;);\r\n    \r\n   \t \/\/ prepare curl for actual image file upload\r\n        \t$url = &quot;https:\/\/www.googleapis.com\/upload\/youtube\/v3\/channelBanners\/insert?key=&quot; .\r\n   \t\t\t $g_youtubeDataAPIKey;\r\n\r\n    \r\n   \t $curl = curl_init();\r\n   \t curl_setopt_array($curl, array(\r\n   \t\t\t\t CURLOPT_HTTPHEADER=&gt;array(&#039;Content-Type: application\/octet-stream&#039;,\r\n   \t\t\t\t\t  &#039;Authorization: OAuth &#039; . $accessToken,\r\n   \t\t\t\t\t  &#039;Content-Length: &#039; . filesize(&quot;channelbanner.png&quot;)   \t\t\t\t\t\t\t ),\r\n   \t\t\t\t CURLOPT_RETURNTRANSFER =&gt; 1,\r\n   \t\t\t\t CURLOPT_URL =&gt; $url,\r\n   \t\t\t\t CURLOPT_USERAGENT =&gt; &#039;YouTube API Tester&#039;,\r\n   \t\t\t\t CURLOPT_SSL_VERIFYPEER =&gt; 1,\r\n   \t\t\t\t CURLOPT_SSL_VERIFYHOST=&gt; 0,\r\n   \t\t\t\t CURLOPT_CAINFO =&gt; &quot;..\/..\/cert\/cacert.pem&quot;,\r\n   \t\t\t\t CURLOPT_CAPATH =&gt; &quot;..\/..\/cert\/cacert.pem&quot;,\r\n   \t\t\t\t CURLOPT_FOLLOWLOCATION =&gt; TRUE,\r\n   \t\t\t\t CURLOPT_CUSTOMREQUEST=&gt;&quot;POST&quot;,\r\n   \t\t\t\t CURLOPT_POSTFIELDS=&gt;$fileData\r\n   \t\t\t\t ));\r\n   \t $resp = curl_exec($curl);\r\n\r\n   \t curl_close($curl);\r\n   \t if ($resp) {\r\n   \t\t $json = json_decode($resp);\r\n   \t\t $imageUrl = $json-&gt;url;\r\n   \t }\r\n   \t if ($imageUrl == null)\r\n   \t\t exit(&quot;Error could not get image url&quot;);\r\n   \t else {\r\n   \t\t echo(&quot;Image url:&quot; . $imageUrl . &quot;&lt;br&gt;&lt;br&gt;&quot;);\r\n\r\n   \t\t  \/\/ run the channel Update API call to update this url in the channel\r\n   \t\t\t\t \r\n   \t\t $image = new Image();\r\n   \t\t $image-&gt;bannerExternalUrl = $imageUrl;\r\n\r\n   \t\t $brandingSettings  = new BrandingSettings();\r\n   \t\t $brandingSettings-&gt;image = $image;\r\n\r\n   \t\t $channel = new ChannelResource();\r\n   \t\t $channel-&gt;id  = $channelId;\r\n   \t\t $channel-&gt;brandingSettings = $brandingSettings;\r\n   \t\t \r\n   \t\t $data = json_encode($channel);\r\n\r\n   \t\t $url = &quot;https:\/\/www.googleapis.com\/youtube\/v3\/channels?part=brandingSettings&amp;key=&quot; .\r\n   \t\t\t $g_youtubeDataAPIKey . &quot;&amp;access_token=&quot; . $accessToken;\r\n\r\n   \t\t $curl = curl_init();\r\n   \t\t curl_setopt_array($curl, array(\r\n   \t\t\t\t CURLOPT_HTTPHEADER=&gt;array(&#039;Content-Type: application\/json&#039;\r\n   \t\t\t\t ),\r\n   \t\t\t\t CURLOPT_RETURNTRANSFER =&gt; 1,\r\n   \t\t\t\t CURLOPT_URL =&gt; $url,\r\n   \t\t\t\t CURLOPT_USERAGENT =&gt; &#039;YouTube API Tester&#039;,\r\n   \t\t\t\t CURLOPT_SSL_VERIFYPEER =&gt; 1,\r\n   \t\t\t\t CURLOPT_SSL_VERIFYHOST=&gt; 0,\r\n   \t\t\t\t CURLOPT_CAINFO =&gt; &quot;..\/..\/cert\/cacert.pem&quot;,\r\n   \t\t\t\t CURLOPT_CAPATH =&gt; &quot;..\/..\/cert\/cacert.pem&quot;,\r\n   \t\t\t\t CURLOPT_FOLLOWLOCATION =&gt; TRUE,\r\n   \t\t\t\t CURLOPT_CUSTOMREQUEST=&gt;&quot;PUT&quot;,\r\n   \t\t\t\t CURLOPT_POSTFIELDS=&gt;$data\r\n   \t\t\t\t ));\r\n   \t $resp = curl_exec($curl);\r\n\r\n   \t curl_close($curl);\r\n\r\n   \t var_dump($resp);\r\n\r\n\r\n   \t\t \r\n   \t }\r\n\r\n    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\r\n\r\n    class ChannelResource {\r\n   \t public $id;\r\n    }\r\n\r\n    class BrandingSettings {\r\n   \t public $image;\r\n    }\r\n\r\n    class Image {\r\n   \t public $bannerExternalUrl;\r\n    }\r\n\r\n?&gt;\r\n<\/pre><\/p>\n<p>Here is the output:<\/p>\n<p><span style=\"color: #999999;\">Image url:https:\/\/lh3.googleusercontent.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/s0-d\/channels4_banner<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #999999;\">string(3498) &#8220;{ &#8220;kind&#8221;: &#8220;youtube#channel&#8221;, &#8220;etag&#8221;: &#8220;\\&#8221;m2yskBQFythfE4irbTIeOgYYfBU\/I5p8iEauGbe17rA6tU4X_0vs0W4\\&#8221;&#8221;, &#8220;id&#8221;: &#8220;UCnXmfpAZ1rLsg0Goh0bBHUA&#8221;, &#8220;brandingSettings&#8221;: { &#8220;channel&#8221;: { &#8220;title&#8221;: &#8220;Amit Sengupta&#8221;, &#8220;defaultTab&#8221;: &#8220;Featured&#8221;, &#8220;profileColor&#8221;: &#8220;#000000&#8221;, &#8220;defaultLanguage&#8221;: &#8220;en&#8221; }, &#8220;image&#8221;: { &#8220;bannerImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w1060-fcrop64=1,00005a57ffffa5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerMobileImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w640-fcrop64=1,32b75a57cd48a5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerTabletLowImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w1138-fcrop64=1,00005a57ffffa5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerTabletImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w1707-fcrop64=1,00005a57ffffa5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerTabletHdImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w2276-fcrop64=1,00005a57ffffa5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerTabletExtraHdImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w2560-fcrop64=1,00005a57ffffa5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerMobileLowImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w320-fcrop64=1,32b75a57cd48a5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerMobileMediumHdImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w960-fcrop64=1,32b75a57cd48a5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerMobileHdImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w1280-fcrop64=1,32b75a57cd48a5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerMobileExtraHdImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w1440-fcrop64=1,32b75a57cd48a5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerTvImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w2120-fcrop64=1,00000000ffffffff-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerTvLowImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w854-fcrop64=1,00000000ffffffff-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerTvMediumImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w1280-fcrop64=1,00000000ffffffff-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221;, &#8220;bannerTvHighImageUrl&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w1920-fcrop64=1,00000000ffffffff-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221; }, &#8220;hints&#8221;: [ { &#8220;property&#8221;: &#8220;channel.featured_tab.template.string&#8221;, &#8220;value&#8221;: &#8220;Everything&#8221; }, { &#8220;property&#8221;: &#8220;channel.banner.mobile.medium.image.url&#8221;, &#8220;value&#8221;: &#8220;https:\/\/yt3.ggpht.com\/-2yueuJ2GfNc\/WSfJ67_xrYI\/AAAAAAAAAqg\/MIVb0xS9fUQA2Cn-ReWLpapK47WOVaPCQCL8B\/w640-fcrop64=1,32b75a57cd48a5a8-nd-c0xffffffff-rj-k-no\/channels4_banner&#8221; } ] } } &#8220;<\/span><\/p>\n<p>As mentioned above, the process requires two separate API calls. We also have an existing png image channelbanner.png which is uploaded.<\/p>\n<p>In the first API call to channelBanner.insert we ensure the following :<\/p>\n<ul>\n<li>Set cURL header to &#8216;Content-Type: application\/octet-stream&#8217; since we are sending the raw contents of the image<\/li>\n<li>Set cURL header to &#8216;Authorization: OAuth &#8216; . $accessToken to pass the access token<\/li>\n<li>Set cURL header to &#8216;Content-Length: &#8216; . filesize(&#8220;channelbanner.png&#8221;) to set the length of the data being posted.<\/li>\n<\/ul>\n<p>On successful execution the response will return a json encoded ChannelBanner Resource. We extract the url property from there . This is the url of the channel banner.<\/p>\n<p>We then execute the next API call to channel.update to set the banner image url. We define the required Channel resource classes and json encode the top level object. We set the url attribute to the value obtained from the previous API call.<\/p>\n<p>We set the following things in the cURL request:<\/p>\n<ul>\n<li>Set header to Content-Type: application\/json since we are sending the Channel object<\/li>\n<li>Set CURLOPT_CUSTOMREQUEST to PUT since this is a PUT request and not a POST<\/li>\n<li>Set CURLOPT_POSTFIELDS to the json encoded Channel object<\/li>\n<\/ul>\n<p>On successful execution, the response contains a json encoded Channel resource object.<\/p>\n<p>This is how the Channel banner looks after uploading channelbanner.png<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-medium wp-image-2839\" src=\"https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2017\/07\/1-620x173.png\" alt=\"1\" width=\"620\" height=\"173\" srcset=\"https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2017\/07\/1-620x173.png 620w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2017\/07\/1-300x84.png 300w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2017\/07\/1-768x215.png 768w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2017\/07\/1-940x263.png 940w, https:\/\/truelogic.org\/wordpress\/wp-content\/uploads\/2017\/07\/1.png 1180w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>This is article 15 of the YouTube API With PHP series. A Channel Banner is the image which shows up the Channel homepage in the <a class=\"mh-excerpt-more\" href=\"https:\/\/truelogic.org\/wordpress\/2017\/07\/08\/15-youtube-data-api-channel-banners\/\" title=\"15 &#8211; YouTube Data API &#8211; Channel Banners\">[&#8230;]<\/a><\/p>\n<\/div>","protected":false},"author":1,"featured_media":2727,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[318],"tags":[],"class_list":["post-2837","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-youtube-api-with-php"],"_links":{"self":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts\/2837","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/comments?post=2837"}],"version-history":[{"count":2,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts\/2837\/revisions"}],"predecessor-version":[{"id":2840,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/posts\/2837\/revisions\/2840"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/media\/2727"}],"wp:attachment":[{"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/media?parent=2837"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/categories?post=2837"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/truelogic.org\/wordpress\/wp-json\/wp\/v2\/tags?post=2837"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}