<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ショートコード | imakat.com</title>
	<atom:link href="https://imakat.com/tag/%e3%82%b7%e3%83%a7%e3%83%bc%e3%83%88%e3%82%b3%e3%83%bc%e3%83%89/feed/" rel="self" type="application/rss+xml" />
	<link>https://imakat.com</link>
	<description>工夫と改善で人生をちょっと豊かに</description>
	<lastBuildDate>Tue, 10 Mar 2026 06:25:58 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://i0.wp.com/imakat.com/wp-content/uploads/2023/07/cropped-80d64ecd340db4e2ca3224859b04caed.png?fit=32%2C32&#038;ssl=1</url>
	<title>ショートコード | imakat.com</title>
	<link>https://imakat.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">160909258</site>	<item>
		<title>第５章〜終わりに：動画パッケージの作り方</title>
		<link>https://imakat.com/2025/04/29/26044/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Tue, 29 Apr 2025 04:41:31 +0000</pubDate>
				<category><![CDATA[マイライブラリ]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[トークンリンク]]></category>
		<category><![CDATA[ファイルパス]]></category>
		<category><![CDATA[ショートコード]]></category>
		<category><![CDATA[識別子]]></category>
		<category><![CDATA[直リンク]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=26044</guid>

					<description><![CDATA[メディアライブラリを作ろう 24年3月「動的サイトを作ってみた」、同12月「動画ショートコード」を作成し、動画配信のためのデータ作成方法を解説してきました。 その後、少し手直しを行ったため、改めて「動画パッケージの作り方 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>メディアライブラリを作ろう</p>



<figure class="wp-block-image size-large is-resized"><a href="https://imakat.com/rd.php?id=kSLZHN3D.png" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=kSLZHN3D.png" alt="" style="width:237px;height:auto"/></a></figure>



<p><a href="https://imakat.com/2024/03/23/20191/" target="_blank">24年3月「動的サイトを作ってみた」</a>、<a href="https://imakat.com/2024/12/22/24182/" target="_blank">同12月「動画ショートコード」</a>を作成し、動画配信のためのデータ作成方法を解説してきました。</p>



<p>その後、少し手直しを行ったため、改めて「動画パッケージの作り方」の解説をします。</p>



<p>なお「動画パッケージ」は、自作のメディアライブラリの中の一つのメニューです。</p>



<h3 class="wp-block-heading"><strong>1</strong>　スクリプトの変更点</h3>



<h4 class="wp-block-heading">ファイルパス入力を不要に：</h4>



<p>当初は、各URLファイルを入力した後、そのファイルパスを別途手で入力していました。これは手間なので、事前にメディアライブラリの中にメディアアセットとして登録済みの場合は、再生URLを登録するだけで、spreadsheetに対して、存在するファイルパスが自動的に呼び出されるよう改良しました。</p>



<figure class="wp-block-image size-large"><a href="https://imakat.com/rd.php?id=HqI14hFc.png" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=HqI14hFc.png" alt=""/></a></figure>



<h3 class="wp-block-heading">２　アプリ運用変更点　</h3>



<h4 class="wp-block-heading">個別指定による再生サーバーの優先：</h4>



<p>第3章で説明したように、再生URLに対しては個別に指定された再生サーバーが優先されます。個別指定がなければ、拡張子別の選択番号が適用されます。</p>



<p>メディアアセットごとにこの再生選択番号が設定され、例えば、以下のようになります。</p>



<figure class="wp-block-image size-large"><a href="https://imakat.com/rd.php?id=ljP56apU.png" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=ljP56apU.png" alt=""/></a></figure>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>https://imakat.com/rd.php?id=5XipZRMG.png</td><td>サーバー選択番号：３</td></tr></tbody></table></figure>



<h4 class="wp-block-heading">拡張子別サーバー選択：</h4>



<p>現状、下のように、３：Xserver(WordPress)、４：pCloud、を選択しています。</p>



<figure class="wp-block-image size-large"><a href="https://imakat.com/rd.php?id=oWNg5PjX.png" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=oWNg5PjX.png" alt=""/></a></figure>



<h4 class="wp-block-heading">所在場所に「dynamic」を追加：</h4>



<p>次に、動画パッケージの設定に入ります。以前にも説明した通り、動画はいくつかのメディアアセットを集めて作ります。このライブラリでは、初期画像ファイルURL、高画質動画ファイルURL、低画質動画ファイルURL、字幕ファイルURL、字幕一覧ファイルURL、説明ファイルURLの6種類です。基本的には、これらの再生URLを登録します。</p>



<p>動画パッケージの設定では、各URLを登録すると同時に再生サーバーも自動決定されます。例えば、初期画像はpCloudから表示、動画はDropboxから表示、字幕はXserverから表示、字幕一覧はpCloudから表示、説明はXserverから表示といったように、自由に設定が出来ます。<strong>動的に自由に場所が変更可能なので、呼び名をdynamicとしました</strong>。<br><strong>ただし、字幕vttファイルについては、WordPressサーバーの中に置くようにします(そうしないと、Windowsの場合は字幕が表示されません)</strong>。</p>



<p>なお、再生URLを入力せずに、サーバー別のURLを直接入力することもできます。その場合は、個別選択、拡張子別選択の影響は受けずに、再生されます。</p>



<p>基礎情報として、いくつかに分類してありますが、この意図は、埋め込みコードの形式の違いをはっきりさせるためです。dynamic、wordpressサーバー、は、いずれもWordPressサーバーのHTML5動画プレーヤーを使用しますので、どれを選んでも同じ結果になります。Vimeo、YouTubeはそれぞれの動画プレーヤーを使うのでhtmlスクリプトも異なります。</p>



<figure class="wp-block-image size-large"><a href="https://imakat.com/rd.php?id=iWOgej34.png"><img decoding="async" src="https://imakat.com/rd.php?id=iWOgej34.png" alt=""/></a></figure>



<h3 class="wp-block-heading">３　ショートコードの生成</h3>



<p>WordPressの投稿には、</p>



<ul class="wp-block-list">
<li>カスタムHTMLブロックに埋め込む方法</li>



<li>ショートコードブロックに記載する方法<br></li>
</ul>



<p>の二つがあり、表示される内容は同じです。</p>



<p>phpスクリプト</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#dddddd"><strong><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1rtcT8lfSgcHDKIzLEsMVpjzNBIZO8TrmHFGkTgBBrNA/edit?usp=sharing">動画ショートコードの例<span class="fa fa-external-link external-icon anchor-icon"></span></a></strong></td></tr></tbody></table></figure>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td colspan="2" style="background-color:#dddddd"><strong>動画ショートコードの生成</strong>(WordPressサーバー内)</td></tr><tr><td colspan="2">指定された videoid に基づいて videoembed.json を取得し、対応するレコードの embedCode を実行して動画を埋め込む。videoid が指定されていない、JSONが取得できない、または該当レコードが見つからない場合は「動画はまだ準備中です。」と表示する。<br></td></tr><tr><td colspan="2"><a href="https://imakat.com/script_list/?pubtxt=動画ショートコードの生成php_pub.txt" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=zrU95MiY.png" alt="" style="width:120px; height:auto;"></a></td></tr></tbody></table></figure>



<h3 class="wp-block-heading">４　動画を使う目的に応じて選択する</h3>



<p>動画のグルーピングは、広く公開したいときは、Vimeo、YouTubeを選択する、ブログの記事用については、ブログは文章や画像で説明を済ませたいところですが、実際の作業や動きを見せて補強した方がいい時は多々あります。その時はdynamicを使う、といった使い分けになります。大事なのは、視聴者の立場で考えること。例えば、ブログ記事の補強で動画を使う場合、大抵は、数分〜10分程度におさまると思いますが、<strong>内容が数分程度のものを見てもらうのに、その前に広告を長々と見てもらうというのは、それはむごいこと、ある意味失礼なことだと、私は、感じます</strong>。だから、そうした動画はdynamic、長くなった場合はVimeoを選びます。<br>YouTubeは、やむを得ない場合使う、という順位に考えています。</p>



<h3 class="wp-block-heading">5　マイライブラリを２ページ並べる</h3>



<p>動画パッケージを作成する手順は、最初に、メディアアセットをマイライブラリに登録することから始めます。次に、その登録されたアセットの再生URL(rd.phpの文字列のある)を、動画パッケージに登録します。この作業は、画面を２分割して、左側に「メディアアセット情報」、右側に「動画パッケージ」を配置すると便利です。それをクリックで表示するAppleScriptを紹介します。</p>



<figure class="wp-block-image size-large"><a href="https://imakat.com/rd.php?id=8lmGpbXm.png" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=8lmGpbXm.png" alt=""/></a></figure>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>SafariでAppSheetの2つのURLを左右に並べて表示するAppleScript。メインディスプレイのサイズを取得し、画面を左右に分割して各URLをそれぞれの位置に開く。Safariを起動後、左側に1つ目のURLを新規ウインドウで開き、続いて右側に2つ目のURLを開く。もし新規ウインドウが作成されずタブ化された場合は、システムイベント経由で新規ウインドウを強制的に生成し、右側に配置する。</td></tr><tr><td><a href="https://imakat.com/script_list/?pubtxt=マイライブラリ画面２分割applescript_pub.txt" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=zrU95MiY.png" alt="" style="width:120px; height:auto;"></a></td></tr></tbody></table></figure>



<h3 class="wp-block-heading">終わりに</h3>



<p>ここまで、メディアライブラリの作成から活用までの流れを説明してきました。</p>



<p>基本の考え方は「ひとつの場所に依存しない」です。<strong>脱YouTube、脱Dropboxです</strong>。</p>



<p>どうしても、人は、「この指とまれ」「このボール、あなたなら奪えるよ」と誘われると、群がる習性があります。そこを狙ったが如く、突然、天災、人災は起こり、その集まりを破壊します。あるいは、物事は、新しく生み出されてしばらくすると、それが普及して大衆化します。大衆化した次は飽和して衰退します。万物同じ原理で動いています。YouTubeは今は儲かっているでしょうが類似のサービスは間違いなく拡大します。YouTubeが未来ずっと存在することは難しいでしょう。<br></p>



<p>&#x27a1;<a href="https://imakat.com/2025/04/03/25693/" target="_blank"> 第１章へ戻る</a></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="has-text-align-center"><a href="https://imakat.com/media_library1" target="_blank">&#x1f517; 目次ページへ戻る</a></p>



<p></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">26044</post-id>	</item>
		<item>
		<title>【WordPress】「動画ショートコード」を作ってみた。〜動画画像ライブラリ2〜</title>
		<link>https://imakat.com/2024/12/22/24182/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Sat, 21 Dec 2024 23:39:00 +0000</pubDate>
				<category><![CDATA[マイライブラリ]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ショートコード]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[GAS]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=24182</guid>

					<description><![CDATA[今回の投稿ですが、以前投稿した、「動画用の動的サイトを作ってみた」の続編の位置付けです。以前作った動的サイトは、&#8221;https://imakat.com/ds5?drid=38&#8220;の形式になっており、 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>今回の投稿ですが、以前投稿した、「<a href="https://imakat.com/2024/03/23/20191/" target="_blank">動画用の動的サイトを作ってみた</a>」の続編の位置付けです。以前作った動的サイトは、&#8221;<a href="https://imakat.com/ds5?drid=38" target="_blank">https://imakat.com/ds5?drid=38</a>&#8220;の形式になっており、どこにでもリンクができる便利モノです。この&#8221;ds5&#8243;の部分は、再生方法の違いの意味を持たせ、&#8221;drid&#8221;の部分は、再生サーバーの違いの意味を持たせました。</p>



<p>しかしもっと簡単に考えて、まず、&#8221;38&#8243;の部分は自分で自由に設定できる動画idです。その動画idにどのサーバーにあるメディアをくっつけるかを決めます。ただし、VimeoやYouTubeの場合は、VimeoやYouTube側でidを発行するので、私がそれと別のidをさらに付けるのも管理を複雑にするだけなので、やめます。その結果、例えば、&#8221;38&#8243;はDropbox、&#8221;alt_38&#8243;は自宅サーバー、”885196700”はVimeo、&#8221;SRpWDu7gFC4&#8243;はYouTubeと動画idを決めることができます。重要なのは、動画idはユニークなキーであることです。</p>



<p>以下のようにショートコードブロックに、ショートコードを埋め込むようにして、&#8221;&#8221;のvideoid(動画id)=の部分を書き換えれば、動画がサクッと置き換わるようになります。</p>



<p>以下が実際のショートコード貼り付けによる動画です。</p>



<pre class="wp-block-code plaintext"><code>&#091;videoembed videoid="40"]</code></pre>


<div class="sc-dynamic-embed">
  <style>
  /* リンクの見た目を整える */
  .sc-dynamic-embed .sc-link-container { 
      display: flex; 
      gap: 12px; 
      margin-bottom: 10px; 
      flex-wrap: wrap; 
      align-items: center; 
  }
  .sc-dynamic-embed .sc-link { margin-bottom: 0; }
  .sc-dynamic-embed .sc-link a {
    font-size: 15px;
    font-weight: normal;
    text-decoration: underline;
    color: #0073aa;
  }
  .sc-dynamic-embed .sc-link a:hover { text-decoration: none; color: #000; }
  
  /* ★変更：ダウンロードボタンの基本サイズを小さくし、文字の折り返しを防止 */
  .sc-dynamic-embed .dl-btn a {
    font-size: 12px !important;
    color: #d9534f;
    font-weight: bold;
    text-decoration: none;
    background: #fdf0ef;
    padding: 4px 6px;
    border-radius: 4px;
    border: 1px solid #d9534f;
    white-space: nowrap; 
  }
  .sc-dynamic-embed .dl-btn a:hover { background: #d9534f; color: #fff; }

  /* ★追加：スマホ画面（幅500px以下）の時は、さらに全体を縮小して1行に収める */
  @media (max-width: 500px) {
    .sc-dynamic-embed .sc-link-container { gap: 6px; }
    .sc-dynamic-embed .sc-link a { font-size: 13px; }
    .sc-dynamic-embed .dl-btn a { font-size: 11px !important; padding: 3px 5px; }
  }

  /* 行梱包時の基本スタイル */
  .sc-dynamic-embed .imk-line {
      display: inline-block;
      width: 100%;
      border-radius: 2px;
      transition: background-color 0.1s;
  }

  /* 古い枠内字幕ボックスを強制消去 */
  .sc-dynamic-embed #subtitleOverlay,
  .sc-dynamic-embed #scSubtitleOverlay,
  .sc-dynamic-embed .overlay-cue,
  .sc-dynamic-embed .band {
      display: none !important;
      opacity: 0 !important;
      visibility: hidden !important;
      pointer-events: none !important;
  }
  </style>

  <div class="sc-link-container">
    <p class="sc-link">
      <a href="https://imakat.com/ds62/?drid=40" target="_blank"
         onclick="return scStopAndGo(event, this);">
        👉低画質・枠外字幕はこちら
      </a>
    </p>
    <p class="sc-link dl-btn">
      <a href="#" id="imk-dynamic-dl-btn" target="_blank" rel="noopener" download style="display: none;">
        📥 動画をダウンロード
      </a>
    </p>
  </div>

  <style>
            :root{ --dr5emd-max: 1920px; }
            .video-wrap{position:relative;width:100%;margin:0 auto}
            figure.wp-block-video.aligncenter{
              width:100%;
              max-width:min(var(--dr5emd-max, 1920px), 98vw);
              margin:0 auto;
            }
            #subtitleOverlay{
              position:absolute; left:0; right:0; bottom:6%;
              padding:0 2%; text-align:center; pointer-events:none; z-index:2;
            }
            #subtitleOverlay .band{
              display:inline-block; background:rgba(0,0,0,0.35);
              padding:6px 10px; border-radius:8px; max-width:96%;
              margin:0 auto; box-shadow:0 1px 2px rgba(0,0,0,0.15);
            }
            #subtitleOverlay .overlay-cue{
              color:#fff; font-weight:600;
              font-size:clamp(16px, 3.6vw, 32px);
              line-height:1.32; white-space:pre-wrap; margin:2px 0;
              -webkit-text-stroke:.6px rgba(0,0,0,.7);
              text-shadow:-1px -1px 0 rgba(0,0,0,.6), 1px -1px 0 rgba(0,0,0,.6),
                          -1px  1px 0 rgba(0,0,0,.6), 1px  1px 0 rgba(0,0,0,.6);
            }
            @media (max-width:430px){
              #subtitleOverlay .overlay-cue{ font-size:clamp(16px, 4.2vw, 22px); }
            }
            .dr5emd-sublist details > p{
              height:200px; overflow:auto; background-color:#EDF7FF;
              padding:2px 6px; margin:0; box-shadow:3px 3px 4px black;
              position: relative;
            }
            .dr5emd-sublist details > summary{
              padding:2px 6px; width:100%;
              background-color:#ddd; border:none;
              box-shadow:3px 3px 4px black; cursor:pointer; list-style:none;
            }
            /* ▼ 自動スクロール時のハイライト（文字の太さを標準へ変更） */
            .active-hl {
                background-color: #ffff00 !important;
                color: #ff0000 !important;
                font-weight: normal; /* 標準の太さ */
                border-bottom: 2px solid red;
                display: inline-block;
                border-radius: 2px;
            }
            </style><div class="dr5emd-container"><figure class="wp-block-video aligncenter"><div class="video-wrap"><video id="myVideo" controls controlsList="nodownload" poster="https://imakat.com/rd.php?id=8vXz9WrK.png" playsinline preload="metadata" style="width:100%;height:auto;">  <source src="https://imakat.com/rd.php?id=6yncKhFV.mov" type="video/mp4">  <track src="https://imakat.com/rd.php?id=RvB8qB84.vtt" label="日本語" srclang="ja" kind="subtitles"></video><div id="subtitleOverlay" aria-hidden="true"></div></div><script>
document.addEventListener("DOMContentLoaded", function(){
  var video=document.getElementById("myVideo");
  var trackEl=video?video.querySelector("track[kind='subtitles'], track[kind='captions']"):null;
  var overlay=document.getElementById("subtitleOverlay"); if(!video||!overlay) return;
  video.addEventListener("contextmenu", function(e){ e.preventDefault(); return false; }, false);
  function setNative(mode){
    try{
      if(video.textTracks && video.textTracks.length){
        for(var i=0;i<video.textTracks.length;i++){ video.textTracks[i].mode = mode; }
      }
      if(trackEl && trackEl.track) trackEl.track.mode = mode;
    }catch(e){}
  }
  var isOverlay=true,lastSig="";
  function sig(active){if(!active||active.length===0)return"";var a=[];for(var i=0;i<active.length;i++){var c=active[i];a.push([c.startTime,c.endTime,c.text].join("|"));}return a.join("||");}
  function cueLine(c){var d=document.createElement("div");d.className="overlay-cue";d.setAttribute("translate","yes");if(typeof c.getCueAsHTML==="function")d.appendChild(c.getCueAsHTML());else d.textContent=c.text;return d;}
  function render(){
    if(!isOverlay || !trackEl || !trackEl.track) return;
    var ac=trackEl.track.activeCues,s=sig(ac); if(s===lastSig) return; lastSig=s;
    overlay.innerHTML=""; if(!ac || ac.length===0) return;
    var b=document.createElement("div"); b.className="band"; b.setAttribute("translate","yes");
    Array.from(ac).sort(function(a,b){return a.startTime-b.startTime;}).forEach(function(c){b.appendChild(cueLine(c));});
    overlay.appendChild(b);
  }
  function useOverlay(){isOverlay=true;overlay.style.display="";setNative("hidden");lastSig="";render();}
  function useNative(){isOverlay=false;overlay.style.display="none";setNative("showing");lastSig="";}
  useOverlay();
  if(trackEl){
    if(trackEl.track){ try{ trackEl.track.addEventListener("cuechange",render); }catch(e){} }
    trackEl.addEventListener("load", function(){ try{ if(trackEl.track) trackEl.track.addEventListener("cuechange",render); }catch(e){} render(); });
  }
  video.addEventListener("loadedmetadata",render);
  function handleWebkitMode(){ var m = video.webkitPresentationMode || "inline"; (m==="picture-in-picture"||m==="fullscreen") ? useNative() : useOverlay(); }
  if("webkitPresentationMode" in video){ video.addEventListener("webkitpresentationmodechanged",handleWebkitMode); handleWebkitMode(); }
  if("webkitCurrentPlaybackTargetIsWireless" in video){
    video.addEventListener("webkitcurrentplaybacktargetiswirelesschanged", function(){ video.webkitCurrentPlaybackTargetIsWireless ? useNative() : useOverlay(); });
  }
  if("pictureInPictureEnabled" in document){
    video.addEventListener("enterpictureinpicture",useNative);
    video.addEventListener("leavepictureinpicture",useOverlay);
  }
  document.addEventListener("fullscreenchange", function(){
    var fs=document.fullscreenElement;
    if(!fs) return useOverlay();
    (fs===video || (fs && fs.contains && fs.contains(video))) ? useNative() : useOverlay();
  });
});
</script>
                <figcaption></figcaption></figure><div class="dr5emd-sublist"><details><summary>字幕一覧(クリック)</summary> <p>
(<a href="#" class="imk-cue" data-seek="0:19">00:00:19</a>) 1) それでは今日は動画webという動画のライブラリーですね。<br>
(<a href="#" class="imk-cue" data-seek="0:30">00:00:30</a>) 2) それを手作りしましたのでそれを紹介していきます。<br>
(<a href="#" class="imk-cue" data-seek="0:36">00:00:36</a>) 3) まず基礎情報としてですね。<br>
(<a href="#" class="imk-cue" data-seek="0:38">00:00:38</a>) 4) ご覧のように有名な配信サーバーの名前がありますけど、<br>
(<a href="#" class="imk-cue" data-seek="0:45">00:00:45</a>) 5) 動画をですね。まず分類しておきます。<br>
(<a href="#" class="imk-cue" data-seek="0:50">00:00:50</a>) 6) 私としてはですね。<br>
(<a href="#" class="imk-cue" data-seek="0:52">00:00:52</a>) 7) Vimeo Dropbox YouTube あと 自宅サーバーですね、<br>
(<a href="#" class="imk-cue" data-seek="1:01">00:01:01</a>) 8) この自宅サーバーというのは自宅WordPressサーバーです。<br>
(<a href="#" class="imk-cue" data-seek="1:08">00:01:08</a>) 9) 以上Vimeo Dropbox YouTube<br>
(<a href="#" class="imk-cue" data-seek="1:14">00:01:14</a>) 10) 自宅サーバーと、この四つを主にですね、使っています。<br>
(<a href="#" class="imk-cue" data-seek="1:23">00:01:23</a>) 11) 次に、それに基づいて作成した動画が、<br>
(<a href="#" class="imk-cue" data-seek="1:31">00:01:31</a>) 12) 例えばこんな形でライブラリーになってます。<br>
(<a href="#" class="imk-cue" data-seek="1:37">00:01:37</a>) 13) この動画idっていうのが、IDコードですね。<br>
(<a href="#" class="imk-cue" data-seek="1:41">00:01:41</a>) 14) 個別の動画に対して振ったナンバー記号です。<br>
(<a href="#" class="imk-cue" data-seek="1:49">00:01:49</a>) 15) この39というのを例えば見てみますと<br>
(<a href="#" class="imk-cue" data-seek="1:52">00:01:52</a>) 16) これはDropbox、<br>
(<a href="#" class="imk-cue" data-seek="1:55">00:01:55</a>) 17) それと次にalt_38というのがこれが自宅サーバー、<br>
(<a href="#" class="imk-cue" data-seek="2:03">00:02:03</a>) 18) それからこの辺に、数字で長い、<br>
(<a href="#" class="imk-cue" data-seek="2:08">00:02:08</a>) 19) 長い数字になってるものが、Vimeo<br>
(<a href="#" class="imk-cue" data-seek="2:16">00:02:16</a>) 20) それからこの辺にあるランダム文字列ですね。<br>
(<a href="#" class="imk-cue" data-seek="2:21">00:02:21</a>) 21) 英数字のランダム文字列のものは、<br>
(<a href="#" class="imk-cue" data-seek="2:24">00:02:24</a>) 22) YouTube、というような形で動画idを振っております。<br>
(<a href="#" class="imk-cue" data-seek="2:35">00:02:35</a>) 23) それで例えばこの最初のですね、39を見てみますけども<br>
(<a href="#" class="imk-cue" data-seek="2:44">00:02:44</a>) 24) Editでどういう情報を登録しているかと言いますと、<br>
(<a href="#" class="imk-cue" data-seek="2:48">00:02:48</a>) 25) まず初めに動画idを振ります。<br>
(<a href="#" class="imk-cue" data-seek="2:51">00:02:51</a>) 26) それから題名をつける、動画の所在場所を選択します。<br>
(<a href="#" class="imk-cue" data-seek="3:01">00:03:01</a>) 27) ついにその動画の初期画像ファイルですね、それを入れます。<br>
(<a href="#" class="imk-cue" data-seek="3:05">00:03:05</a>) 28) 基本的にその動画サーバーと同じ位置になります。<br>
(<a href="#" class="imk-cue" data-seek="3:12">00:03:12</a>) 29) この場合はDropboxの、<br>
(<a href="#" class="imk-cue" data-seek="3:14">00:03:14</a>) 30) Dropboxリンクを入れてあります。<br>
(<a href="#" class="imk-cue" data-seek="3:19">00:03:19</a>) 31) あとそのファイルの物理的な所在位置を記録しておきます→後日、自動登録に改善→字幕一覧にリンク。<br>
(<a href="#" class="imk-cue" data-seek="3:26">00:03:26</a>) 32) あとそれとサムネイルとしての初期画像、<br>
(<a href="#" class="imk-cue" data-seek="3:30">00:03:30</a>) 33) 次に、これがメインである動画ファイルURL、<br>
(<a href="#" class="imk-cue" data-seek="3:38">00:03:38</a>) 34) これもこの場合はdropboxリンクです。<br>
(<a href="#" class="imk-cue" data-seek="3:43">00:03:43</a>) 35) その動画のファイルパス、次に字幕ファイルです<br>
(<a href="#" class="imk-cue" data-seek="3:52">00:03:52</a>) 36) ただしこの字幕ファイルにおいてはですね、<br>
(<a href="#" class="imk-cue" data-seek="3:56">00:03:56</a>) 37) WordPressの制約で、<br>
(<a href="#" class="imk-cue" data-seek="3:59">00:03:59</a>) 38) 配信するWordPressサーバーの中に置くということが、<br>
(<a href="#" class="imk-cue" data-seek="4:04">00:04:04</a>) 39) 条件になってますので、自分の外部配信サーバーの中にですね、<br>
(<a href="#" class="imk-cue" data-seek="4:14">00:04:14</a>) 40) vttファイルを置いているという例です。<br>
(<a href="#" class="imk-cue" data-seek="4:20">00:04:20</a>) 41) それから次にこれは字幕ファイルのパスです。<br>
(<a href="#" class="imk-cue" data-seek="4:25">00:04:25</a>) 42) ローカルパスです。次がその字幕一覧ファイルですね。<br>
(<a href="#" class="imk-cue" data-seek="4:30">00:04:30</a>) 43) 字幕を外側に一覧表として掲示するものです。<br>
(<a href="#" class="imk-cue" data-seek="4:35">00:04:35</a>) 44) これはDropboxリンクです。<br>
(<a href="#" class="imk-cue" data-seek="4:39">00:04:39</a>) 45) 次はそのパスですね、<br>
(<a href="#" class="imk-cue" data-seek="4:43">00:04:43</a>) 46) あとそれから必要ならば、説明のための文章、<br>
(<a href="#" class="imk-cue" data-seek="4:47">00:04:47</a>) 47) テキストファイルでくっつけるという形になっています。<br>
(<a href="#" class="imk-cue" data-seek="4:52">00:04:52</a>) 48) 普通はその公開しますので、公開を選びます。<br>
(<a href="#" class="imk-cue" data-seek="4:59">00:04:59</a>) 49) こうして作った情報をsaveしますと、<br>
(<a href="#" class="imk-cue" data-seek="5:02">00:05:02</a>) 50) キャンセルしますけども、既にあるので、そうすると<br>
(<a href="#" class="imk-cue" data-seek="5:10">00:05:10</a>) 51) そうするとこのようにですね、出来上がるわけですね。<br>
(<a href="#" class="imk-cue" data-seek="5:14">00:05:14</a>) 52) このJSON更新というのを押しますと<br>
(<a href="#" class="imk-cue" data-seek="5:17">00:05:17</a>) 53) そのファイルが外部のWordPressサーバーの方に飛んでいきます。<br>
(<a href="#" class="imk-cue" data-seek="5:32">00:05:32</a>) 54) これを具体的に再生してみたいと思います。<br>
(<a href="#" class="imk-cue" data-seek="6:03">00:06:03</a>) 55) このように出来上がっています。<br>
(<a href="#" class="imk-cue" data-seek="6:09">00:06:09</a>) 56) それから再生URLと合わせてですね、<br>
(<a href="#" class="imk-cue" data-seek="6:13">00:06:13</a>) 57) 投稿の中でも紹介していますが<br>
(<a href="#" class="imk-cue" data-seek="6:16">00:06:16</a>) 58) WordPressのショートコード、<br>
(<a href="#" class="imk-cue" data-seek="6:19">00:06:19</a>) 59) WordPressのショートコードブロックへ記入するものですけれども、<br>
(<a href="#" class="imk-cue" data-seek="6:25">00:06:25</a>) 60) このようにここに掲載してあります。以上です。<br>
</p> </details>
<style>
details { font: 16px "Open Sans", Calibri, sans-serif; width: 100%; }
details > summary { padding: 2px 6px; width: 100%; background-color: #ddd; border: none; box-shadow: 3px 3px 4px black; cursor: pointer; list-style: none; }
details > p { font: 14px "Open Sans", Calibri, sans-serif; height:150px; overflow: scroll; background-color: #EDF7FF; padding: 2px 6px; margin: 0; box-shadow: 3px 3px 4px black; }
</style>
</div><script>
(function(){
  var root=document.querySelector(".dr5emd-sublist");
  var video=document.getElementById("myVideo");
  if(!root || !video) return;
  function parseTs(ts){
    if(!ts) return null;
    var p=ts.trim().split(":").map(function(x){return parseInt(x,10)||0;});
    if(p.length===2) return p[0]*60 + p[1];
    if(p.length===3) return p[0]*3600 + p[1]*60 + p[2];
    return null;
  }
  root.addEventListener("click", function(e){
    var a=e.target.closest && e.target.closest("a.imk-cue[data-seek]");
    if(!a || !root.contains(a)) return;
    e.preventDefault();
    var sec = parseTs(a.getAttribute("data-seek"));
    if(sec==null) return;
    try{ video.currentTime = sec; if(video.paused) video.play(); }catch(_){}
  });
  video.addEventListener("timeupdate", function(){
    var listContainer = root.querySelector("details > p");
    if(!listContainer) return;
    var cues = listContainer.querySelectorAll("a.imk-cue");
    if(cues.length === 0) return;
    var cur = video.currentTime;
    var active = null;
    for(var i=0; i<cues.length; i++){
        var t = parseTs(cues[i].getAttribute("data-seek"));
        if(t !== null && cur >= t - 0.5){
            active = cues[i];
        } else if(t > cur){
            break;
        }
    }
    if(active){
        if(active.classList.contains("active-hl")) return;
        var old = listContainer.querySelectorAll(".active-hl");
        for(var k=0; k<old.length; k++) old[k].classList.remove("active-hl");
        active.classList.add("active-hl");
        if(listContainer.offsetParent !== null){
            var containerRect = listContainer.getBoundingClientRect();
            var activeRect = active.getBoundingClientRect();
            var targetScroll = listContainer.scrollTop + (activeRect.top - containerRect.top) - (listContainer.clientHeight / 2) + (active.clientHeight / 2);
            listContainer.scrollTo({ top: targetScroll, behavior: "smooth" });
        }
    }
  });
})();
</script>
                </div>

  <script>
  (function(){
    var me = document.currentScript;
    var wrapper = me ? me.closest('.sc-dynamic-embed') : null;

    /* -----------------------------------------------
       1. ダウンロードボタンの自動セットアップ機能
       ----------------------------------------------- */
    function setupDownloadButton() {
      var target = wrapper ? wrapper : document;
      var video = target.querySelector('video');
      var dlBtn = target.querySelector('#imk-dynamic-dl-btn');

      if (video && dlBtn && dlBtn.style.display === 'none') {
        var src = video.currentSrc || video.src;
        if (!src) {
          var source = video.querySelector('source');
          if (source) src = source.src;
        }
        if (src) {
          dlBtn.href = src;
          dlBtn.style.display = 'inline-block';
        }
      }
    }

    /* -----------------------------------------------
       2. 字幕制御＆ハイライト機能（iPhone全画面 完全対応版）
       ----------------------------------------------- */
    function initSubtitles() {
      var target = wrapper ? wrapper : document;
      var video = target.querySelector('video');
      var listContainer = target.querySelector('details > p');
      
      if (!video || !listContainer) return false; 

      if (video.dataset.subInit === 'true') return true; 
      video.dataset.subInit = 'true';

      var oldOverlay = target.querySelector('#subtitleOverlay') || target.querySelector('#scSubtitleOverlay');
      if (oldOverlay) {
          oldOverlay.style.setProperty('display', 'none', 'important');
          oldOverlay.innerHTML = ''; 
      }

      function isSpecialMode() {
        var isFs = !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement);
        var isPiP = !!(document.pictureInPictureElement && document.pictureInPictureElement === video) || (video.webkitPresentationMode === "picture-in-picture");
        var isIOSFs = !!video.webkitDisplayingFullscreen; 
        return isFs || isPiP || isIOSFs;
      }

      try {
        if(video.textTracks && video.textTracks.length > 0){
          for(var i=0; i<video.textTracks.length; i++){
             if(video.textTracks[i].kind === 'subtitles' || video.textTracks[i].kind === 'captions'){
                 video.textTracks[i].mode = "hidden";
             }
          }
        }
      } catch(e){}

      video.addEventListener("webkitbeginfullscreen", function() {
          try {
              if(video.textTracks && video.textTracks.length > 0) {
                  for(var i=0; i<video.textTracks.length; i++){
                      if(video.textTracks[i].kind === 'subtitles' || video.textTracks[i].kind === 'captions') video.textTracks[i].mode = "showing";
                  }
              }
          } catch(e){}
      });
      video.addEventListener("webkitendfullscreen", function() {
          try {
              if(video.textTracks && video.textTracks.length > 0) {
                  for(var i=0; i<video.textTracks.length; i++){
                      if(video.textTracks[i].kind === 'subtitles' || video.textTracks[i].kind === 'captions') video.textTracks[i].mode = "hidden";
                  }
              }
          } catch(e){}
      });

      var detailsEl = target.querySelector("details");
      if (detailsEl) {
          detailsEl.open = true; 
          var summaryEl = detailsEl.querySelector("summary");
          if (summaryEl) summaryEl.textContent = "字幕(シーン)はここをクリック";
      }

      if (!listContainer.dataset.formatted) {
          var html = listContainer.innerHTML;
          var lines = html.split(/<br\s*\/?>/i);
          var newHtml = "";
          for(var j=0; j<lines.length; j++) {
              if(lines[j].trim() === "") continue;
              newHtml += "<span class='imk-line'>" + lines[j] + "</span><br>";
          }
          listContainer.innerHTML = newHtml;
          listContainer.dataset.formatted = "true";
      }

      function parseTs(ts){
        if(!ts) return null;
        var p = ts.trim().split(":").map(function(x){return parseInt(x,10)||0;});
        if(p.length===2) return p[0]*60 + p[1];
        if(p.length===3) return p[0]*3600 + p[1]*60 + p[2];
        return null;
      }

      var rootSublist = target.querySelector(".dr5-sublist") || listContainer.parentElement;
      if (rootSublist) {
        rootSublist.addEventListener("click", function(e){
          var a = e.target.closest && e.target.closest("a.imk-cue[data-seek]");
          if(!a) return;
          e.preventDefault();
          var sec = parseTs(a.getAttribute("data-seek"));
          if(sec==null) return;
          try{ video.currentTime = sec; if(video.paused) video.play(); }catch(_){}
        });
      }

      video.addEventListener("timeupdate", function(){
        var desiredMode = isSpecialMode() ? "showing" : "hidden";
        try {
            if(video.textTracks && video.textTracks.length > 0){
                for(var i=0; i<video.textTracks.length; i++){
                    if((video.textTracks[i].kind === 'subtitles' || video.textTracks[i].kind === 'captions') && video.textTracks[i].mode !== desiredMode) {
                        video.textTracks[i].mode = desiredMode;
                    }
                }
            }
        } catch(e){}

        var cues = listContainer.querySelectorAll("a.imk-cue");
        if(cues.length === 0) return;
        var cur = video.currentTime;
        var activeA = null;

        for(var i=0; i<cues.length; i++){
            var t = parseTs(cues[i].getAttribute("data-seek"));
            if(t !== null && cur >= t - 0.5){ activeA = cues[i]; } 
            else if(t > cur){ break; }
        }

        if(activeA){
            var activeLine = activeA.closest(".imk-line");
            if(!activeLine) activeLine = activeA;

            if(activeLine.classList.contains("active-hl")) return;

            var allLines = listContainer.querySelectorAll(".imk-line");
            for(var k=0; k<allLines.length; k++) {
                allLines[k].classList.remove("active-hl");
                allLines[k].removeAttribute("style"); 
            }
            var allLinks = listContainer.querySelectorAll("a");
            for(var m=0; m<allLinks.length; m++) {
                allLinks[m].classList.remove("active-hl");
                allLinks[m].removeAttribute("style"); 
            }

            activeLine.classList.add("active-hl");
            activeLine.style.setProperty("background-color", "#ffff00", "important");
            activeLine.style.setProperty("color", "red", "important");
            activeLine.style.setProperty("font-weight", "normal", "important");
            
            var newLinks = activeLine.querySelectorAll("a");
            for(var n=0; n<newLinks.length; n++) {
                newLinks[n].style.setProperty("color", "red", "important");
                newLinks[n].style.setProperty("text-decoration", "none", "important");
            }

            if(listContainer.offsetParent !== null){
                var containerRect = listContainer.getBoundingClientRect();
                var activeRect = activeLine.getBoundingClientRect();
                var targetScroll = listContainer.scrollTop + (activeRect.top - containerRect.top) - (listContainer.clientHeight / 2) + (activeLine.clientHeight / 2);
                listContainer.scrollTo({ top: targetScroll, behavior: "smooth" });
            }
        }
      });

      return true;
    }

    /* -----------------------------------------------
       監視タイマー（URL抜き出し＆ボタン表示を継続的に実行）
       ----------------------------------------------- */
    var checks = 0;
    var checkTimer = setInterval(function(){
      setupDownloadButton();
      var success = initSubtitles();
      checks++;
      if (success || checks > 20) { 
        clearInterval(checkTimer);
      }
    }, 500); 

    /* -----------------------------------------------
       3. 画面遷移時の停止機能
       ----------------------------------------------- */
    if (!window.scStopAndGo) {
      window.scStopAndGo = function(event, link){
        try{
          var mediaEls = document.querySelectorAll('video, audio');
          mediaEls.forEach(function(m){
            try{
              if (!m.paused) m.pause();
              if (document.pictureInPictureElement === m && document.exitPictureInPicture) {
                document.exitPictureInPicture().catch(function(){});
              }
            }catch(e){}
          });
        }finally{
          event.preventDefault();
          setTimeout(function(){
            if (link.target === '_blank') {
              window.open(link.href, '_blank');
            } else {
              window.location.href = link.href;
            }
          }, 50);
        }
        return false;
      };
    }
  })();
  </script>
</div>



<p>自分が作成した動画、YouTubeから探し出した動画などにidをつけて、動画ライブラリに登録しておけば、あとは利用が簡単です。</p>



<figure class="wp-block-image size-large is-resized"><a href="https://imakat.com/rd.php?id=b39zvke2.png" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=b39zvke2.png" alt="" style="width:172px;height:auto"/></a></figure>



<h3 class="wp-block-heading">ポイント解説</h3>



<p>それでは、この動画ショートコードの作成について、手順を説明します。下に全体図を掲載します。全部で４ステップになります。</p>



<a rel="noopener" target="_blank" href="https://docs.google.com/drawings/d/1vRNmldbsN9LanVByLJpSw8lZnzuK14bfaomVEEChHb8/edit?usp=sharing" 
>
<img decoding="async" src="https://docs.google.com/drawings/d/e/2PACX-1vRxo6t770TaUUmE9ecoA90UeG9F9pZs5lbLp2GjoqCdB4ZpFY8GyAInpXM1cGPwngqu_qpdmzXJI3WC/pub?w=960&#038;h=720"
></a>



<h4 class="wp-block-heading"><span class="bold-red">❶</span>　サーバーごとに埋め込みコードテンプレートを作成する。</h4>



<p>現在、用意しているのは、Dropbox、Vimeo、YouTube、自宅サーバーの４つになりますが、埋め込みコードの書き方は、それぞれ違いがあります。Dropboxと自宅サーバーは、WordPress動画プレーヤーの使用方法に従って記述し、Vimeo、YouTubeはサイトで提供される貼り付け、埋め込みコードを参考にして記述して、それらのテンプレートを作成します。</p>



<p><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1BR-YsIQKI1zPJ_ASNPveT9bWyjHvi4ZSWqETW-IwPw4/edit?usp=sharing">Dropbox 埋め込みテンプレートの生成&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a><br><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1zt39qvh0IpxxzjEiN8eHfbxkBpPSJ2lp-iOpY8OHtDM/edit?usp=sharing">Vimeo 埋め込みテンプレートの生成&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a><br><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1YEnUd5ofUD_kwRVy1WE0Ga0RwsaaK7jSTz096_uuEcs/edit?usp=sharing">YouTube 埋め込みテンプレートの生成&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a><br><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1xWKvYvja8jY5gHNHDq8E0MAa-VegQaOp1F6o1Q3T8tY/edit?usp=sharing">自宅サーバー 埋め込みテンプレートの生成&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<h4 class="wp-block-heading"><span class="bold-red">❷</span>　動画idごとに埋め込みコードを生成する。</h4>



<p>動画idファイル(spreadsheet)のS列(19列)に埋め込みコードを追記します。この埋め込みコードは、そのままWordPressのカスタムhtmlブロックへコピペすれば使えます。まず、その状態を作ります。</p>



<p><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1eQqf0Ug8M_jeCAU4vFz4mfj1HQD-RE6wKaPMSyM09sw/edit?usp=sharing">動画idごとに埋め込みコードを生成GAS&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<h4 class="wp-block-heading"><span class="bold-red">❸</span>　埋め込みコードをJSONに書き込み、WordPressサーバーへ送る。</h4>



<p>埋め込みコードをコピペするだけでも便利ではありますが、欠点もあります。ソースコードは見る人が見れば外から丸わかりなのでURLをコピーできます。巡回ロボットを使えばもっと簡単です。それを拡散できるわけですが、やたら拡散されてしまうことは非常に迷惑なことですので避けたいです。「漠然とした拡散は迷惑である」とするこの感覚が、SNSとの決定的な違いになります。</p>



<p>その意味で、「動的サイト」や「動画ショートコード」には、動画のURLまでは表記しませんので、やや、安全になります。埋め込みコードの欠点のあと一つは、複数箇所に書き込んでいて、もし動画他のURLを差し替えようとした時、複数箇所の修正をする必要があること、当たり前のことではありますが、これが結構ストレスになります。この点、元となる動画webサイトをメンテナンスすれば全部変更されます。</p>



<p><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1yM4xRPzqiLS7Q-GdzeVRqRE3RSSxboIErOHssiX3V-k/edit?usp=sharing">埋め込みコードJSON生成GAS&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<p>videoembed.jsonファイルは、gd_wp_dataに書き出されます。gd_wp_dataフォルダはHazelによって監視されており変化した場合はTransmit5のFTPにより数分以内にXserverにあるWordPressサーバーへ更新されます。</p>



<h4 class="wp-block-heading"><span class="bold-red">❹</span>　動画ショートコードphpを作成する。</h4>



<p>WordPressサーバー側では、投稿で記述されたショートコードとマッチするvideoembed.jsonファイル内の埋め込みコードに基づき、動画を再生します。</p>



<p>その処理を行うphpを、Cocoon childのfunctions.phpに追記します。<br><br><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1cBKsLnwutNZZVO32spPKdBYV1hP5HCwQJlp-C2tj_fw/edit?usp=sharing">動画ショートコード起動php&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a><br><br></p>



<h4 class="wp-block-heading">まとめ</h4>



<p>まとめになりますが、この動画ショートコードは、以前に投稿した、動的サイトの運用とセットになります。ぜひ、そちらもご一読ください→「<a href="https://imakat.com/2024/03/23/20191/" target="_blank">動画用の動的サイトを作ってみた</a>」。</p>



<p>以上です。<br><br></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">24182</post-id>	</item>
	</channel>
</rss>
