{"id":48997,"date":"2020-05-13T03:01:27","date_gmt":"2020-05-12T17:01:27","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=48997"},"modified":"2020-05-12T20:41:26","modified_gmt":"2020-05-12T10:41:26","slug":"html-canvas-video-display-filters-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/html-canvas-video-display-filters-tutorial\/","title":{"rendered":"HTML Canvas Video Display Filters Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/canvas_createpattern_video.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML Canvas Video Display Filters Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/canvas_createpattern_video_effects.jpg\" title=\"HTML Canvas Video Display Filters Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">HTML Canvas Video Display Filters Tutorial<\/p><\/div>\n<p>We&#8217;re adding some new functionality onto the recent <a title='HTML Canvas Video Display Primer Tutorial' href='#htmlcvdpt'>HTML Canvas Video Display Primer Tutorial<\/a>, that being &#8230;<\/p>\n<ul>\n<li>turn the &#8220;Video&#8221; hardcoded text, on the webpage &#8230; into an &#8220;a&#8221; link &#8230;<br \/>\n<code><br \/>\n&lt;a style=\"cursor:pointer;text-decoration:underline;\" onclick=\"askv();\"&gt;Video&lt;\/a&gt;<br \/>\n<\/code><br \/>\n &#8230; calling on the Javascript function &#8230;<br \/>\n<code><br \/>\n  function askv() {<br \/>\n    var vurl=prompt(\"Enter a video URL (if you click OK to blank entry we'll open a local file browse window).\", \"\");<br \/>\n    if (vurl != null) {<br \/>\n      if (vurl == \"\") {<br \/>\n        document.getElementById('cvideo').click();  \/\/ browse for video file on local device<br \/>\n        found=false;<br \/>\n        lookfor();<br \/>\n      } else {<br \/>\n        location.href=document.URL.split('#')[0].split('?')[0] + '?vurl=' + encodeURIComponent(vurl);  \/\/ reload with video URL<br \/>\n      }<br \/>\n    }<br \/>\n  }<br \/>\n<\/code>\n<\/li>\n<li>to allow for a &#8220;reload with video URL&#8221; &#8230;<br \/>\n<code><br \/>\n&lt;script type='text\/javascript'&gt;<br \/>\n<br \/>\n  var types = [\"video\/mp4\",\"image\/svg\",\"audio\/wav\",\"audio\/x-wav\",\"audio\/x-pn-realaudio\",\"audio\/x-mpegurl\",\"audio\/x-aiff\",\"audio\/mpeg\",\"audio\/mid\",<br \/>\n      \"audio\/basic\",\"audio\/ogg\",\"video\/x-sgi-movie\",\"video\/x-msvideo\",\"video\/quicktime\",\"audio\/mp3\",\"video\/mp4\",\"video\/mpeg\",<br \/>\n      \"video\/x-la-asf\",\"video\/ogg\",\"video\/webm\",\"audio\/mp4\", \"image\/jpeg\", \"image\/jpeg\", \"image\/png\", \"image\/gif\", \"image\/bmp\", \"image\/tif\",<br \/>\n      \"text\/html\", \"text\/html\", \"text\/html\", \"text\/javascript\", \"text\/css\", \"text\/plain\", \"text\/xml\", \"text\/csv\",<br \/>\n      \"application\/vnd.ms-word\", \"application\/vnd.openxmlformats-officedocument.wordprocessingml.document\", \"application\/x-php\", \"application\/pdf\",<br \/>\n      \"application\/vnd.openxmlformats-officedocument.presentationml.presentation\", \"application\/vnd.ms-powerpoint\",<br \/>\n      \"application\/vnd.ms-excel\", \"application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"];<br \/>\n  var exts = [\".mp4\",\".svg\",\".wav\",\".wav\",\".ram\",\".m3u\",\".aiff\",\".mp3\",\".rmi\",<br \/>\n      \".snd\",\".ogg\",\".movie\",\".avi\",\".mov\",\".mp3\",\".m4v\",\".mpeg\",<br \/>\n      \".lsx\",\".ogv\",\".webm\",\".m4a\", \".jpg\", \".jpeg\", \".png\", \".gif\", \".bmp\", \".tif\",<br \/>\n      \".htm\", \".html\", \".htmls\", \".js\", \".css\", \".txt\", \".xml\", \".csv\",<br \/>\n      \".doc\", \".docx\", \".php\", \".pdf\",<br \/>\n      \".pptx\", \".ppt\",<br \/>\n      \".xls\", \".xlsx\"];<br \/>\n<br \/>\n var ourmimetype=\"\";<br \/>\n var vnameis=location.search.split('vurl=')[1] ? decodeURIComponent(location.search.split('vurl=')[1].split('&')[0]) : 'ants_reversed.mp4';<br \/>\n for (var ji=0; ji&lt;exts.length; ji++) {<br \/>\n      if ((\".\" + vnameis.split('.')[eval(-1 + vnameis.split('.').length)]).toLowerCase() == exts[ji].toLowerCase()) {<br \/>\n        ourmimetype=types[ji];<br \/>\n      }<br \/>\n }<br \/>\n<br \/>\n&lt;\/script&gt;<br \/>\n<\/code><br \/>\n &#8230; dovetailing with <font color=blue>the new<\/font> &#8230;<br \/>\n<code><br \/>\n<font color=blue>&lt;script type='text\/javascript'&gt;<br \/>\n  document.write(\"<\/font>&lt;video <font color=blue>id=vvideo <\/font>data-style=display:none; controls&gt;&lt;source <font color=blue>id=vsource <\/font>src=<font color=blue>\" + vnameis + \"<\/font> type=<font color=blue>\" + ourmimetype + \"<\/font>&gt;&lt;\/video&gt;<font color=blue>\");<br \/>\n&lt;\/script&gt;<\/font><br \/>\n<\/code>\n<\/li>\n<li>to allow for a &#8220;browse for video file on local device&#8221; &#8230;<br \/>\n<code><br \/>\n  function lookfor() {<br \/>\n    if (!found) {<br \/>\n      if (document.getElementById('cvideo').value != \"\") {<br \/>\n        document.getElementById('vbut').click();<br \/>\n      } else {<br \/>\n        setTimeout(lookfor, 1000);<br \/>\n      }<br \/>\n    }<br \/>\n  }<br \/>\n<\/code><br \/>\n &#8230;<br \/>\n<code><br \/>\n &lt;input style=\"display:none;\" type=\"file\" name=\"video\" id=\"cvideo\" accept=\"video\/*\"&gt;&lt;\/input&gt;&lt;span class=readVBytesButtons&gt;&lt;button style=display:none; data-startbyte=0 data-endbyte=4&gt;1-5&lt;\/button&gt;&lt;button style=display:none; data-startbyte=5 data-endbyte=14&gt;6-15&lt;\/button&gt;&lt;button style=display:none; data-startbyte=6 data-endbyte=7&gt;7-8&lt;\/button&gt;&lt;button id=vbut style=background-color:pink;display:none;&gt;Video Process&lt;\/button&gt;&lt;\/span&gt;<br \/>\n<\/code><br \/>\n &#8230;<br \/>\n<code><br \/>\n  document.querySelector('.readVBytesButtons').addEventListener('click', function(evt) {<br \/>\n    if (evt.target.tagName.toLowerCase() == 'button') {<br \/>\n      var startByte = evt.target.getAttribute('data-startbyte');<br \/>\n      var endByte = evt.target.getAttribute('data-endbyte');<br \/>\n      readVBlob(startByte, endByte);<br \/>\n    }<br \/>\n  }, false);<br \/>\n<\/code><br \/>\n &#8230;<br \/>\n<code><br \/>\n  var mfil=null;<br \/>\n<br \/>\n  function readVBlob(opt_startByte, opt_stopByte) {<br \/>\n    var file = document.getElementById('cvideo').files[0];<br \/>\n    mfile = file;<br \/>\n    document.getElementById('vsource').type=mfile.type;<br \/>\n    var start = parseInt(opt_startByte) || 0;<br \/>\n    var stop = parseInt(opt_stopByte) || mfile.size - 1;<br \/>\n<br \/>\n    var reader = new FileReader();<br \/>\n<br \/>\n    \/\/ If we use onloadend, we need to check the readyState.<br \/>\n    reader.onloadend = function(e) {<br \/>\n      if (e.target.readyState == FileReader.DONE) { \/\/ DONE == 2<br \/>\n      document.getElementById('dvideo').innerHTML='&lt;video id=vvideo data-style=display:none; controls&gt;&lt;source id=vsource type=' + document.getElementById('vsource').type + ' src=\"' + e.target.result + '\"&gt;&lt;\/source&gt;&lt;\/video&gt;';<br \/>\n      initCanvas();<br \/>\n      }<br \/>\n    };<br \/>\n<br \/>\n    var blob = mfile.slice(start, stop + 1);<br \/>\n    reader.readAsDataURL(mfile); \/\/blob);<br \/>\n  }<br \/>\n<\/code>\n<\/li>\n<li>to allow for <font color=blue>some changed<\/font> &#8230;<br \/>\n<code><br \/>\nHTML<br \/>\n&lt;select onchange=\"<font color=blue>qangle='-0.0'; dorotate=false; inversev=false; grayscalev=false; doflip=false; doflop=false;<\/font> rep=scratchit(this.value);\"&gt;&lt;option value='repeat'&gt;Repeat&lt;\/option&gt;&lt;option value='no-repeat'&gt;No Repeat&lt;\/option&gt;<font color=blue>&lt;option value='Repeat'&gt;Grayscale Repeat&lt;\/option&gt;&lt;option value='No-repeat'&gt;Grayscale No Repeat&lt;\/option&gt;&lt;option value='rEpeat'&gt;Inverse Repeat&lt;\/option&gt;&lt;option value='nO-repeat'&gt;Inverse No Repeat&lt;\/option&gt;&lt;option value='repEat'&gt;Flip Repeat&lt;\/option&gt;&lt;option value='no-Repeat'&gt;Flip No Repeat&lt;\/option&gt;&lt;option value='repeAt'&gt;Flop Repeat&lt;\/option&gt;&lt;option value='no-rEpeat'&gt;Flop No Repeat&lt;\/option&gt;&lt;option value='repeaT'&gt;Rotate Repeat&lt;\/option&gt;&lt;option value='no-rePeat'&gt;Rotate No Repeat&lt;\/option&gt;<\/font>&lt;\/select&gt;<br \/>\n<br \/>\nJavascript initializations ...<br \/>\n  <font color=blue>var inversev=false, grayscalev=false;<br \/>\n  var doflip=false, doflop=false;<br \/>\n  var qangle='-0.0', dorotate=false;<\/font><br \/>\n<br \/>\nJavascript changed function ...<br \/>\n  function scratchit(inr) {<br \/>\n    if (('' + inr).toLowerCase().indexOf('no-') == 0) {<br \/>\n      scratch.width = eval('' + iwis);<br \/>\n      scratch.height = eval('' + ihis);<br \/>\n    }<br \/>\n    <font color=blue>if (('' + inr + ' ').substring(0,1) == ('' + inr + ' ').substring(0,1).toUpperCase()) {<br \/>\n      grayscalev=true;<br \/>\n    } else if (('' + inr + '  ').substring(1).substring(0,1) == ('' + inr + '  ').substring(1).substring(0,1).toUpperCase()) {<br \/>\n      inversev=true;<br \/>\n    } else if (('' + inr + '    ').substring(3).substring(0,1) == ('' + inr + '    ').substring(3).substring(0,1).toUpperCase()) {<br \/>\n      doflip=true;<br \/>\n    } else if (('' + inr + '     ').substring(4).substring(0,1) == ('' + inr + '     ').substring(4).substring(0,1).toUpperCase()) {<br \/>\n      doflop=true;<br \/>\n    } else if (('' + inr + '      ').substring(5).substring(0,1) == ('' + inr + '      ').substring(5).substring(0,1).toUpperCase()) {<br \/>\n      if (qangle == '-0.0') { qangle=prompt('How many degrees rotation do you want?', ''); if (qangle == null) { qanghle='-0.0'; } }<br \/>\n      if (qangle.replace('-0.0','').trim() != '') { dorotate=true; } else { dorotate=false; }<br \/>\n    }<\/font><br \/>\n    return inr;<br \/>\n  }<br \/>\n<\/code><br \/>\n &#8230; canvas data Filtering &#8230;<\/p>\n<ol>\n<li>Grayscale (in similar way to <a target=_blank href='https:\/\/www.rjmprogramming.com.au\/ITblog\/feedback-annotation-canvas-image-filter-tutorial' title='Feedback Annotation Canvas Image Filter Tutorial'>Feedback Annotation Canvas Image Filter Tutorial<\/a>)<\/li>\n<li>Inverse (in similar way to <a target=_blank href='https:\/\/www.rjmprogramming.com.au\/ITblog\/feedback-annotation-canvas-image-filter-tutorial' title='Feedback Annotation Canvas Image Filter Tutorial'>Feedback Annotation Canvas Image Filter Tutorial<\/a>)<\/li>\n<li>Flip (in similar way to <a target=_blank href='https:\/\/www.rjmprogramming.com.au\/ITblog\/feedback-annotation-canvas-image-filter-tutorial' title='Feedback Annotation Canvas Image Filter Tutorial'>Feedback Annotation Canvas Image Filter Tutorial<\/a>)<\/li>\n<li>Flop (in similar way to <a target=_blank href='https:\/\/www.rjmprogramming.com.au\/ITblog\/feedback-annotation-canvas-image-filter-tutorial' title='Feedback Annotation Canvas Image Filter Tutorial'>Feedback Annotation Canvas Image Filter Tutorial<\/a>)<\/li>\n<li>Rotated Canvas &#8230;<br \/>\n<code><br \/>\nfunction crotate(ioo, ione, itwo, ithree, ifour, ifive, isix, iseven, ieight) {  \/\/ thanks to https:\/\/www.w3schools.com\/tags\/canvas_getimagedata.asp<br \/>\n var qcos=Math.cos(qangle * Math.PI \/ 180);<br \/>\n var qsin=Math.sin(qangle * Math.PI \/ 180);<br \/>\n sctxt.transform(qcos, qsin, -qsin, qcos, 0, 0);<br \/>\n context.transform(qcos, qsin, -qsin, qcos, 0, 0);<br \/>\n}<br \/>\n<\/code>\n<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<p>You can retry for yourself at <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/canvas_createpattern_video.html--GETME\" title=\"canvas_createpattern_video.html\">the changed<\/a> <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/canvas_createpattern_video.html--GETME\" title=\"canvas_createpattern_video.html\">canvas_createpattern_video.html<\/a>&#8216;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/canvas_createpattern_video.html\" title=\"Click picture\">live run<\/a> link.<\/p>\n<p><!--p>You can also see this play out at WordPress 4.1.1's <a target=_blank  href='\/\/www.rjmprogramming.com.au\/ITblog\/html-canvas-video-display-filters-tutorial\/'>HTML Canvas Video Display Filters Tutorial<\/a>.<\/p-->\n<hr>\n<p id='htmlcvdpt'>Previous relevant <a target=_blank title='HTML Canvas Video Display Primer Tutorial' href='\/\/www.rjmprogramming.com.au\/ITblog\/html-canvas-video-display-primer-tutorial\/'>HTML Canvas Video Display Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/canvas_createpattern_video.html\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"HTML Canvas Video Display Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/canvas_createpattern_video_zoom_bigger_screenresize.gif\" title=\"HTML Canvas Video Display Primer Tutorial\"  style=\"float:left;\" \/><\/a><p class=\"wp-caption-text\">HTML Canvas Video Display Primer Tutorial<\/p><\/div>\n<p>In doing the research for yesterday&#8217;s <a target=_blank title='HTML Canvas Pros and Cons Inline HTML Email Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/html-canvas-pros-and-cons-inline-html-email-tutorial'>HTML Canvas Pros and Cons Inline HTML Email Tutorial<\/a>&#8216;s heavy use of the stupendous HTML(5) <a target=_blank title='HTML Canvas element information from w3schools' href='http:\/\/www.w3schools.com\/tags\/ref_canvas.asp'>canvas<\/a> element we came upon a very interesting discovery, at least for us, that being the <a target=_blank title='HTML canvas createPattern() Method information from W3schools' href='https:\/\/www.w3schools.com\/tags\/canvas_createpattern.asp'>HTML canvas createPattern() Method<\/a>.  Have you read this webpage yet?  <font color=blue>Did you notice &#8230;<\/font><\/p>\n<blockquote cite='http:\/\/www.w3schools.com\/tags\/ref_canvas.asp'><p>\nDefinition and Usage<br \/>\nThe createPattern() method repeats the specified element in the specified direction.<br \/>\n<br \/>\nThe element can be an image, <font color=blue>video<\/font>, or another &lt;canvas&gt; element.<br \/>\n<br \/>\nThe repeated element can be used to draw\/fill rectangles, circles, lines etc.\n<\/p><\/blockquote>\n<p>?  So modestly put, in a list like that, but the implications so big, would you not say <font size=1>&#8230; eh wot, guv&#8217;?!<\/font><\/p>\n<p>No examples followed, alas, but a scouring of the &#8220;net&#8221; arrived at <a target=_blank title='The Definitive Guide to HTML5 Video' href='https:\/\/books.google.com.au\/books?id=IxhnNqaaW_IC&#038;pg=PA183&#038;dq=canvas+createPattern+video+example&#038;hl=en&#038;sa=X&#038;ved=0ahUKEwjIkvP5hKjpAhUXzjgGHWmgA7cQ6AEIKDAA#v=onepage&#038;q=canvas%20createPattern%20video%20example&#038;f=false'>The Definitive Guide to HTML5 Video<\/a> (ISBN: 978-1-4302-3091-5) mention on a <a target=_blank title='Google' href='https:\/\/google.com'>Google<\/a> search, thanks everyone!<\/h4>\n<p>This gave us great scope for a proof of concept web application we got going so long as we clicked (and so the <a target=_blank href='https:\/\/www.w3schools.com\/html\/html5_video.asp' title='HTML video element information from w3schools'>video<\/a> becomes visible) on the controls of a video element (to play it), as is now the go with a lot of platforms, when it comes to working with (and amongst) media forms.  A video plays, and the canvas createPattern helps project &#8220;repeat&#8221; or &#8220;no-repeat&#8221; (controllable to user, a concept similar to how background images can work) onto the right hand table cell&#8217;s canvas via a hidden smaller canvas conduit, the widths and heights controllable to the user as well (all the way to, perhaps, having the canvas be bigger than the video, and so zoom into it (and maybe zoom out the screen) as you can see with today&#8217;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/canvas_createpattern_video_zoom_bigger_screenresize.gif\" title='Tutorial picture'>animated GIF tutorial picture<\/a>).  In that tutorial picture, also take a quick skeg at macOS two finger gesture&#8217;s video &#8220;Picture in Picture&#8221; functionality, too.<\/p>\n<p>Pretty interesting start to a journey we think there&#8217;ll be more to talk about into the future.  You can try for yourself at the &#8220;proof of concept&#8221; <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/canvas_createpattern_video.html-GETME\" title=\"canvas_createpattern_video.html\">canvas_createpattern_video.html<\/a>&#8216;s <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/HTMLCSS\/canvas_createpattern_video.html\" title=\"Click picture\">live run<\/a> link.<\/p>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d48975' onclick='var dv=document.getElementById(\"d48975\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/canvas\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d48975' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d48997' onclick='var dv=document.getElementById(\"d48997\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/mimetype\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d48997' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;re adding some new functionality onto the recent HTML Canvas Video Display Primer Tutorial, that being &#8230; turn the &#8220;Video&#8221; hardcoded text, on the webpage &#8230; into an &#8220;a&#8221; link &#8230; &lt;a style=&#8221;cursor:pointer;text-decoration:underline;&#8221; onclick=&#8221;askv();&#8221;&gt;Video&lt;\/a&gt; &#8230; calling on the Javascript function &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/html-canvas-video-display-filters-tutorial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,14,37],"tags":[1993,184,1580,3297,418,1840,431,433,2440,2439,652,760,2732,2362,997,1072,1238,1319,1345,1369],"class_list":["post-48997","post","type-post","status-publish","format-standard","hentry","category-elearning","category-event-driven-programming","category-tutorials","tag-browse","tag-canvas","tag-cell","tag-createpattern","tag-file","tag-filereader","tag-filter","tag-filters","tag-grayscale","tag-inverse","tag-javascript","tag-media","tag-mimetype","tag-play","tag-programming","tag-rotation","tag-table","tag-tutorial","tag-url","tag-video"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/48997"}],"collection":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/comments?post=48997"}],"version-history":[{"count":3,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/48997\/revisions"}],"predecessor-version":[{"id":49002,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/48997\/revisions\/49002"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=48997"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=48997"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=48997"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}