<?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>WordPress | imakat.com</title>
	<atom:link href="https://imakat.com/category/it/wordpress-ja/feed/" rel="self" type="application/rss+xml" />
	<link>https://imakat.com</link>
	<description>工夫と改善で人生をちょっと豊かに</description>
	<lastBuildDate>Thu, 12 Mar 2026 02:44:11 +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>WordPress | 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>pCloudを動画や画像の配信に使う方法</title>
		<link>https://imakat.com/2025/12/14/28025/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Sun, 14 Dec 2025 02:54:35 +0000</pubDate>
				<category><![CDATA[マイライブラリ]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[pcloud]]></category>
		<category><![CDATA[CDN]]></category>
		<category><![CDATA[ダイレクトリンク]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=28025</guid>

					<description><![CDATA[〜pCloudはスイスにあるクラウドストレージを提供する会社〜 最近、Black Fridayなどで目にすることが増えたpCloud。スイスにあるクラウドストレージを提供する会社で、「買い切りプランも選べる、プライバシー [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p><strong>〜pCloudはスイスにあるクラウドストレージを提供する会社〜</strong></p>



<p>最近、Black Fridayなどで目にすることが増えたpCloud。スイスにあるクラウドストレージを提供する会社で、「買い切りプランも選べる、プライバシー重視のオンライン倉庫」です。ここで紹介しますが、何も営業的な意図はありません。</p>



<p><strong>～Dropboxが廃止したパブリックフォルダを、pCloudでは使える～</strong></p>



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



<p><br>昔からのDropboxユーザーなら記憶にあることですが、以前はパブリックフォルダがあり、ここからWeb配信が可能でした。Dropboxは企業やビジネス用途が多くて漏洩厳禁なところ、フォルダを間違えて公開するようなうっかりミスが多発することも問題だったようです。Dropboxのパブリックフォルダは「便利すぎて危険」「無料すぎて悪用される」「事業の軸と合わない」として廃止したわけです。pCloudは、パブリックフォルダは、もともと公開利用を前提に設計されていて、それを売りにしていることもあるので、一応大丈夫だとは思います。ただ、いずれにしても、クラウドストレージをメディア配信用に使うときには、２つの心得があります。それは、<strong>一つは、配信サーバーが提供する共有リンクをそのまま公開しないこと、もう一つは、一ヶ所の配信サーバーに依存しないこと</strong>です。<br>それでは、解説ビデオをご覧ください。<br></p>


<div class="sc-dynamic-embed">
  <style>
  /* リンクの見た目を整える */
  .sc-dynamic-embed .sc-link-container { 
      display: flex; 
      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; /* dynamicと合わせた基本サイズ */
    font-weight: normal;
    text-decoration: underline;
    color: #0073aa;
  }
  .sc-dynamic-embed .sc-link a:hover { text-decoration: none; color: #000; }
  
  /* ★スマホ画面（幅500px以下）の時は文字を縮小して統一感を出す */
  @media (max-width: 500px) {
    .sc-dynamic-embed .sc-link a { font-size: 13px; }
  }

  /* 行梱包時の基本スタイル */
  .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=68_2" target="_blank"
         onclick="return scStopAndGo(event, this);">
        👉低画質・枠外字幕はこちら
      </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=HpJbDDCm.png" playsinline preload="metadata" style="width:100%;height:auto;">  <source src="https://imakat.com/rd.php?id=PPk0v48b.mp4" type="video/mp4">  <track src="https://imakat.com/rd.php?id=cuPsc5PE.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 translate="yes"><summary translate="yes">字幕一覧(クリック)</summary> <p translate="yes">
(<a href="#" class="imk-cue" data-seek="0:00" translate="no">00:00:00</a>)  〜pCloudを動画や画像の配信に使う方法〜<br>
(<a href="#" class="imk-cue" data-seek="0:18" translate="no">00:00:18</a>)  今みなさんは、こうしてブログから動画をご覧になっているわけですが　<br>
(<a href="#" class="imk-cue" data-seek="0:28" translate="no">00:00:28</a>)  ＜通信状況の良否で配信サーバーを切り替えます＞<br>
(<a href="#" class="imk-cue" data-seek="0:36" translate="no">00:00:36</a>)  だからそれが何だと言われても、反論の余地はないのですが、<br>
(<a href="#" class="imk-cue" data-seek="0:44" translate="no">00:00:44</a>)  言えるのは、最近、クラウドストレージの中で<br>
(<a href="#" class="imk-cue" data-seek="0:48" translate="no">00:00:48</a>)  このpCloudが、やけにネットで広告が目立つと思いませんか。<br>
(<a href="#" class="imk-cue" data-seek="0:57" translate="no">00:00:57</a>)  多分、買い切りがあるところが魅力なのだと思いますね。<br>
(<a href="#" class="imk-cue" data-seek="1:03" translate="no">00:01:03</a>)  私は2025年に0.5TBを約2万円で購入しました。<br>
(<a href="#" class="imk-cue" data-seek="1:13" translate="no">00:01:13</a>)  私は、このpCloudについては、パブリックフォルダが使える、<br>
(<a href="#" class="imk-cue" data-seek="1:22" translate="no">00:01:22</a>)  パブリックフォルダから動画や画像が配信できる点が、大きな魅力の一つだと思っています。<br>
(<a href="#" class="imk-cue" data-seek="1:32" translate="no">00:01:32</a>)  pCloudのテーマに入る前に、私が運用している、動画画像の配信の流れについて、説明します。<br>
(<a href="#" class="imk-cue" data-seek="1:46" translate="no">00:01:46</a>)  図解します。<br>
(<a href="#" class="imk-cue" data-seek="1:50" translate="no">00:01:50</a>)  動画や画像を制作するための、その元になる材料が、製造工程であるDropboxに入ります。　<br>
(<a href="#" class="imk-cue" data-seek="2:03" translate="no">00:02:03</a>)  FinalCutProや画像ソフト、音楽ソフトで、加工します。<br>
(<a href="#" class="imk-cue" data-seek="2:13" translate="no">00:02:13</a>)  そうしたメディアの完成品のうち、インターネットで配信するものを、配信用アセットと呼びますが、それを保存します。<br>
(<a href="#" class="imk-cue" data-seek="2:27" translate="no">00:02:27</a>)  さらにそれを配信所へ配送します。<br>
(<a href="#" class="imk-cue" data-seek="2:35" translate="no">00:02:35</a>)  Dropboxは、Dropbox自身から直接に配信できます。<br>
(<a href="#" class="imk-cue" data-seek="2:44" translate="no">00:02:44</a>)  産直ですね<br>
(<a href="#" class="imk-cue" data-seek="2:47" translate="no">00:02:47</a>)  他に、Xserver 、pCloud、Vimeo、YouTubeを配信所として利用できるようにしています<br>
(<a href="#" class="imk-cue" data-seek="2:58" translate="no">00:02:58</a>)  配信所には高機能の配信所と普通レベルの配信所があります。<br>
(<a href="#" class="imk-cue" data-seek="3:06" translate="no">00:03:06</a>)  高機能の配信所は、ユーザーの受信環境に応じて、複数の画質を自動的に切り替えてくれる、トランスコーディングという機能を持っています。<br>
(<a href="#" class="imk-cue" data-seek="3:23" translate="no">00:03:23</a>)  Vimeo、Youtubeがそれになります<br>
(<a href="#" class="imk-cue" data-seek="3:28" translate="no">00:03:28</a>)  まあ配信専業の会社のサーバーですね。<br>
(<a href="#" class="imk-cue" data-seek="3:36" translate="no">00:03:36</a>)  それに対して、普通レベルの配信所は、画質の自動切り替えはできません。<br>
(<a href="#" class="imk-cue" data-seek="3:47" translate="no">00:03:47</a>)  私の例だと、Dropbox Xserver pCloud、これらがそうです。<br>
(<a href="#" class="imk-cue" data-seek="3:56" translate="no">00:03:56</a>)  ふつうにクラウドストレージと呼ばれる会社群といっていいですね。<br>
(<a href="#" class="imk-cue" data-seek="4:04" translate="no">00:04:04</a>)  これらはデータを格納するのが主な役割で、配信機能はおまけと言ってもいいかも知れません。<br>
(<a href="#" class="imk-cue" data-seek="4:18" translate="no">00:04:18</a>)  ただコスパが非常にいいので、騙し騙し使えるように、　<br>
(<a href="#" class="imk-cue" data-seek="4:25" translate="no">00:04:25</a>)  高画質動画と低画質動画のどちらかを、ユーザーが選択できるようにしました。<br>
(<a href="#" class="imk-cue" data-seek="4:36" translate="no">00:04:36</a>)  最近、世の中全体の、ネットの高速化が、進んでいますので、<br>
(<a href="#" class="imk-cue" data-seek="4:42" translate="no">00:04:42</a>)  このふつうレベルの配信所でも、十分、実用になっています。<br>
(<a href="#" class="imk-cue" data-seek="4:48" translate="no">00:04:48</a>)  そこまでが、配信所までの流れです。<br>
(<a href="#" class="imk-cue" data-seek="4:52" translate="no">00:04:52</a>)  他方、ユーザーからの表示のリクエストがWordPressに入ってきます。<br>
(<a href="#" class="imk-cue" data-seek="5:00" translate="no">00:05:00</a>)  そのリクエストを配信所へ取りに行く<br>
(<a href="#" class="imk-cue" data-seek="5:08" translate="no">00:05:08</a>)  とってきたものを、表示する、<br>
(<a href="#" class="imk-cue" data-seek="5:13" translate="no">00:05:13</a>)  そういう操作になります。<br>
(<a href="#" class="imk-cue" data-seek="5:20" translate="no">00:05:20</a>)  それでは、次に、今回の主役である、pCloudの活用のテーマに入っていきます。<br>
(<a href="#" class="imk-cue" data-seek="5:32" translate="no">00:05:32</a>)  ふつう、ユーザーが、メディアや書類を、配信したり他人に渡すとき、ダイレクトリンクを使いますよね。<br>
(<a href="#" class="imk-cue" data-seek="5:45" translate="no">00:05:45</a>)  このダイレクトリンクを取得しますね。<br>
(<a href="#" class="imk-cue" data-seek="5:49" translate="no">00:05:49</a>)  あるいは共有リンクと呼びますかね。<br>
(<a href="#" class="imk-cue" data-seek="5:54" translate="no">00:05:54</a>)  そのリンクをメールやブログに貼り付けるわけですね。<br>
(<a href="#" class="imk-cue" data-seek="6:01" translate="no">00:06:01</a>)  ファイル名に日本語が入っていると、こんなような、%の入った、複雑な文字列になっています。<br>
(<a href="#" class="imk-cue" data-seek="6:14" translate="no">00:06:14</a>)  そのリンクをクリックすると、こんなように表示されます。<br>
(<a href="#" class="imk-cue" data-seek="6:23" translate="no">00:06:23</a>)  さらに。。名前変更テスト。。<br>
(<a href="#" class="imk-cue" data-seek="6:28" translate="no">00:06:28</a>)  しかし、ローカル側で、うっかり、ファイルを移動したりファイル名を変更してしまうことがありますよね。<br>
(<a href="#" class="imk-cue" data-seek="6:40" translate="no">00:06:40</a>)  その時に、そのファイルを、ダイレクトリンクを通じて、別の人が利用していたりすると、<br>
(<a href="#" class="imk-cue" data-seek="6:57" translate="no">00:06:57</a>)  表示が不可能となり、迷惑をかけてしまうことになります。<br>
(<a href="#" class="imk-cue" data-seek="7:10" translate="no">00:07:10</a>)  だから、このリンク切れを防ぐ方法を考えたいわけです。人はポカを犯しますからね。<br>
(<a href="#" class="imk-cue" data-seek="7:18" translate="no">00:07:18</a>)  そこで、よく使われる方法が、不変のIDを使う方法です。<br>
(<a href="#" class="imk-cue" data-seek="7:30" translate="no">00:07:30</a>)  まあ、マイナンバーのようなものです。<br>
(<a href="#" class="imk-cue" data-seek="7:33" translate="no">00:07:33</a>)  そのマイナンバーに、さまざまな情報が登録されているような形です。<br>
(<a href="#" class="imk-cue" data-seek="7:40" translate="no">00:07:40</a>)  ファイルパスの変更というのは、住所の変更や氏名の変更と同じことです。<br>
(<a href="#" class="imk-cue" data-seek="7:49" translate="no">00:07:49</a>)  要するに、マイナンバーを使おうという考えです。<br>
(<a href="#" class="imk-cue" data-seek="7:54" translate="no">00:07:54</a>)  ただマイナンバーというと、人に知られては困るものですよね。<br>
(<a href="#" class="imk-cue" data-seek="8:00" translate="no">00:08:00</a>)  ところが、この不変のIDは、マイナンバーと全く違って、公開されるということです。<br>
(<a href="#" class="imk-cue" data-seek="8:09" translate="no">00:08:09</a>)  こんな感じですね。<br>
(<a href="#" class="imk-cue" data-seek="8:14" translate="no">00:08:14</a>)  先におみせした、％のついたダイレクトリンクを使うのではなく、<br>
(<a href="#" class="imk-cue" data-seek="8:20" translate="no">00:08:20</a>)  独自に、不変のID で作った再生URLを、メールやブログに貼り付けて、<br>
(<a href="#" class="imk-cue" data-seek="8:28" translate="no">00:08:28</a>)  提供するようにする、ということです。<br>
(<a href="#" class="imk-cue" data-seek="8:32" translate="no">00:08:32</a>)  こうすることにより、<br>
(<a href="#" class="imk-cue" data-seek="8:40" translate="no">00:08:40</a>)  このURLをクリックしますと、画像が表示されます。<br>
(<a href="#" class="imk-cue" data-seek="8:51" translate="no">00:08:51</a>)  ここで、ファイル名が「さらに」となっていますが、「さらにさらに」と名前を変えたとします。<br>
(<a href="#" class="imk-cue" data-seek="9:06" translate="no">00:09:06</a>)  しかし、再生　URLは、元のままです。画像は同じように表示されます。<br>
(<a href="#" class="imk-cue" data-seek="9:19" translate="no">00:09:19</a>)  次のページからは、ちょっと詳細の話になります。<br>
(<a href="#" class="imk-cue" data-seek="9:29" translate="no">00:09:29</a>)  このwpidexというところに、先ほどの不変のIDが入っていますね。<br>
(<a href="#" class="imk-cue" data-seek="9:44" translate="no">00:09:44</a>)  一方、pCloudサーバー側は、ファイル１つに対して、不変のID=fileidを割り当てています。<br>
(<a href="#" class="imk-cue" data-seek="9:58" translate="no">00:09:58</a>)  この両者をカップリングすれば、いいわけです。<br>
(<a href="#" class="imk-cue" data-seek="10:08" translate="no">00:10:08</a>)  次は、さらに詳細です。<br>
(<a href="#" class="imk-cue" data-seek="10:12" translate="no">00:10:12</a>)  そのfileidを、pCloudサーバーから取得するのには、一工夫が必要になります。<br>
(<a href="#" class="imk-cue" data-seek="10:20" translate="no">00:10:20</a>)  その手順です。<br>
(<a href="#" class="imk-cue" data-seek="10:23" translate="no">00:10:23</a>)  細かいのでブログをお読みいただけばと思います。<br>
(<a href="#" class="imk-cue" data-seek="10:31" translate="no">00:10:31</a>)  最後に豆知識を一つ付けています。これも、ブログをお読みいただければと思います。<br>
(<a href="#" class="imk-cue" data-seek="10:42" translate="no">00:10:42</a>)  それでは、今回の解説はここまでとします。ありがとうございました。<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. 動画の保護機能（右クリック禁止・DL防止）
       ----------------------------------------------- */
    function protectVideo() {
      var target = wrapper ? wrapper : document;
      var mediaEls = target.querySelectorAll('video');
      mediaEls.forEach(function(v){
        if(v.dataset.protected === 'true') return;
        v.dataset.protected = 'true';
        v.setAttribute('controlsList', 'nodownload');
        v.oncontextmenu = function() { return false; };
        v.addEventListener('contextmenu', function(e){ e.preventDefault(); return false; }, false);
      });
    }

    /* -----------------------------------------------
       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;
    }

    /* -----------------------------------------------
       監視タイマー
       ----------------------------------------------- */
    var checks = 0;
    var checkTimer = setInterval(function(){
      protectVideo(); // ★dynamic2は保護を維持
      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>



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



<h4 class="wp-block-heading">１　スクリプト</h4>



<p>新規追加または変更があると、wpidexをキー項目とした、Dropboxリンク、直リンク、ファイルパスを中心に成り立つF1_メディアライブラリファイルのsheet1(シート)が最初に更新され、次に以下のpcloudid(シート)が更新されます。<br></p>



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



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>このスクリプトは、Googleスプレッドシートの「pcloudid」と「sheet1」を基に、pCloud上のファイル情報を自動更新し、filedn形式の直接URLを生成・管理するGASです。sheet1(シート)に新規追加された未登録のwpidexをpcloudid(シート)へ自動追加し、needs_updateがTRUEの行のみを対象に、filepathやfileidからpCloud APIを用いてメタ情報とパスを解決します。生成したdirect_urlや更新日時を反映し、最終的に全データをlast_update順に整列したうえで、pcloud_library.jsonをGoogle Drive上の固定IDファイルへ上書き出力します。</td></tr><tr><td><a href="https://imakat.com/script_list/?pubtxt=pCloud用再生URLおよびJSON生成_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><tr><td>コード(スクリプト)をもっと知りたい方はこちらへ↓</td></tr><tr><td><a rel="noopener" target="_blank" href="https://gemini.google.com/gem/1Dp-NLSA5j5OXE3B1Ki2IaBRCvq4CGa6t?usp=sharing"><img decoding="async" src="https://imakat.com/rd.php?id=s7BMZHhB.png" alt="" style="width:120px; height:auto;"></a></td></tr></tbody></table></figure>



<p></p>



<h4 class="wp-block-heading">２　fileidの取得とダイレクトリンクの生成</h4>



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



<p></p>



<h4 class="wp-block-heading">３　＜豆知識＞　ファイル名を変更することにより、キャッシュ更新を早める</h4>



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



<p>※：<a rel="noopener" target="_blank" href="https://ja.wikipedia.org/wiki/コンテンツデリバリネットワーク">CDN<span class="fa fa-external-link external-icon anchor-icon"></span></a>方式<br>ファイルパスやファイル名の変更は、一般には、好まれませんが、ファイル名の変更はファイルの更新履歴を新しくするので、新たなファイルとして読み込みが起きます。これは、更新処理のスクリプトが安定していることが必須です。<br><br>以上</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">28025</post-id>	</item>
		<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>第４章：リンク切れを防ぐ仕組みほか</title>
		<link>https://imakat.com/2025/04/26/25984/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Sat, 26 Apr 2025 11:06:57 +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[Dropbox]]></category>
		<category><![CDATA[Webホスティング]]></category>
		<category><![CDATA[識別子]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=25984</guid>

					<description><![CDATA[メディアライブラリを作ろう 大手YouTubeなどに依存せず、独自に配信を行うのであれば、小規模な配信所を複数確保し、さらにそれらを迅速に切り替えられる仕組みを整えることが重要です。ここまでの章では、配信所には「トークン [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>メディアライブラリを作ろう</p>



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



<p>大手YouTubeなどに依存せず、独自に配信を行うのであれば、小規模な配信所を複数確保し、さらにそれらを迅速に切り替えられる仕組みを整えることが重要です。<br>ここまでの章では、配信所には「トークンリンク方式」と「直リンク方式」があり、それぞれに特徴と注意点があることを説明してきました。</p>



<ul class="wp-block-list">
<li><strong>トークンリンク方式</strong>は、大手クラウドが採用しており、セキュリティ重視。そのうちDropboxなど限られたサービスのみが配信向きです。</li>



<li><strong>直リンク方式</strong>は、Webサーバーがインストールできれば、その中で容易に構築できますが、エンコード済みURLを管理する必要があり、リンク切れ対策が不可欠です。</li>
</ul>



<p>この章では、特に「リンク切れを防ぐ仕組み作り」について具体的に説明していきます。</p>



<h3 class="wp-block-heading"><strong>1. Dropboxへの依存リスク</strong>〜【脱Dropbox】は可能か〜</h3>



<p>トークンリンク方式には大きな利点があります。<br>ファイルパスやファイル名を変更しても、共有リンクURL（トークンリンク）は基本的に変更されません。<br>これにより、配信側にとって運用が非常に安定します。</p>



<p>しかし、<strong>ストリーミング再生に対応したトークンリンク方式</strong>を許可しているクラウドサービスは非常に少なく、現状では<strong>Dropbox</strong>がほぼ唯一の選択肢となっています。<br>このため、Dropboxに頼ってしまう、配信インフラをDropboxのみに依存するリスクが懸念されます。<br>では、Dropboxの代替となるクラウドは存在するのでしょうか？ 次に、主要なクラウドストレージの状況をまとめてみます。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#dddddd"></td><td style="background-color:#dddddd"><strong>トークンリンク方式のクラウド</strong></td><td style="background-color:#dddddd"><strong>ファイルパスから共有リンク取得</strong></td><td style="background-color:#dddddd"><strong>共有リンクからストリーミング表示可能か</strong></td><td style="width:30%;background-color:#dddddd"><strong>コメント</strong></td></tr><tr><td><img data-recalc-dims="1" decoding="async" width="150" height="150" class="wp-image-23536" style="width: 150px;" src="https://i0.wp.com/imakat.com/wp-content/uploads/2024/08/apps.23871.13668225141277943.68205d94-7cbe-41f0-893f-53305fceb682.4c98395a-28d0-4eee-9b6e-08ecd210e980.png?resize=150%2C150&#038;ssl=1" alt=""></td><td><strong>Dropbox</strong></td><td>可能 &#x2705;(API使用)</td><td>可能 &#x2705;（raw=1 などで直再生可）</td><td style="width:30%">Mac Finderパスとクラウドパスが一致、取得容易。dl=0をraw=1に変換でストリーミング。</td></tr><tr><td><img data-recalc-dims="1" decoding="async" width="150" height="134" class="wp-image-26007" style="width: 150px;" src="https://i0.wp.com/imakat.com/wp-content/uploads/2025/04/efb949124a22b7e8531beeaa646f299b.png?resize=150%2C134&#038;ssl=1" alt=""></td><td><strong>Google Drive</strong></td><td>工夫すれば可能 △</td><td>部分的に可能 △（制限あり）</td><td style="width:30%">API検索でファイルID取得可能。基本はビューアーページ誘導。ファイル種別・設定次第で挙動が変わる。</td></tr><tr><td><img data-recalc-dims="1" decoding="async" width="150" height="110" class="wp-image-26009" style="width: 150px;" src="https://i0.wp.com/imakat.com/wp-content/uploads/2025/04/9cc2564f50d59bc8e0dd4add9c49cb9f.png?resize=150%2C110&#038;ssl=1" alt=""></td><td><strong>OneDrive</strong></td><td>工夫すれば可能 △</td><td>部分的に可能 △（制限あり）</td><td style="width:30%">API経由でパス整形可能。ストリーミング可否はファイル形式やブラウザに依存。</td></tr><tr><td><img data-recalc-dims="1" loading="lazy" decoding="async" width="150" height="103" class="wp-image-26008" style="width: 150px;" src="https://i0.wp.com/imakat.com/wp-content/uploads/2025/04/0950888e1f0b5b1fffae2a277d0086d7.png?resize=150%2C103&#038;ssl=1" alt=""></td><td><strong>iCloud Drive</strong></td><td>ほぼ不可能 &#x274c;</td><td>ほぼ不可能 &#x274c;</td><td style="width:30%">API経由での共有リンク取得不可。共有リンクもストリーミングに適さない。</td></tr></tbody></table></figure>



<p>このように、複数のクラウドをトークンリンク方式で使い分けることは現実的ではなく、<strong>トークンリンク方式についてはDropboxに一本化する</strong>のが最も合理的な選択だと言えます。繰り返し言います。それゆえに、Dropboxに依存したくなるのですが、サービスが永続する保証など無く、そこにリスクがあるわけです。</p>



<figure class="wp-block-image size-full is-resized"><a href="https://i0.wp.com/imakat.com/wp-content/uploads/2025/07/006fc22b73c6d589b68264a753102b7a.png?ssl=1" target="_blank"><img data-recalc-dims="1" loading="lazy" decoding="async" width="600" height="581" src="https://i0.wp.com/imakat.com/wp-content/uploads/2025/07/006fc22b73c6d589b68264a753102b7a.png?resize=600%2C581&#038;ssl=1" alt="" class="wp-image-26550" style="width:121px;height:auto" srcset="https://i0.wp.com/imakat.com/wp-content/uploads/2025/07/006fc22b73c6d589b68264a753102b7a.png?w=600&amp;ssl=1 600w, https://i0.wp.com/imakat.com/wp-content/uploads/2025/07/006fc22b73c6d589b68264a753102b7a.png?resize=500%2C484&amp;ssl=1 500w" sizes="(max-width: 600px) 100vw, 600px" /></a></figure>



<h3 class="wp-block-heading"><strong>2. <strong>直リンク方式による配信とリンク切れ対策</strong></strong></h3>



<p>一方、<strong>直リンク方式</strong>ならば、Dropboxに依存せずに複数の配信所を設けることが可能です。<br>具体的な候補は以下のようなものがあります。</p>



<ul class="wp-block-list">
<li><strong>pCloud(パブリックフォルダ利用)</strong></li>



<li><strong>WordPressサーバー(Xserverなど)</strong></li>



<li><strong>自宅Webサーバー</strong></li>



<li><strong>レンタルWebサーバー（独自ドメイン）</strong></li>
</ul>



<p>※pCloudは今では特異な存在で、トークンリンク方式と直リンク方式の両方を提供しています。昔のDropboxに似ています。pCloudは使い勝手のいい仕組みを持っているのですが、サーバーが欧州と北米にしかないので、遅延が生じ易いです。日本にサーバーがあればかなり有用だと思います。</p>



<p>これらはいずれも、ドメイン名直下またはサブディレクトリに<strong>メディアフォルダをコピーするだけ</strong>で、新たな配信拠点をすぐに追加できます。</p>



<p>ただし、ここで問題になるのが、ファイルパスやファイル名の変更に伴う<strong>リンク切れ</strong>です。</p>



<p>これを防ぐために、次のような仕組みを用意します。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td colspan="2" style="background-color:#dddddd"><strong>バックグラウンド処理</strong>(常時監視する)&#x2b07;&#xfe0f;</td></tr><tr><td colspan="2">ファイルパス、ファイル名の変更前と変更後を記録する。</td></tr><tr><td colspan="2"><a href="https://imakat.com/script_list/?pubtxt=ファイルパス変更処理_gasからpython移行_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>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td colspan="2" style="background-color:#dddddd"><strong>メディアフォルダの更新方法</strong>(第２章のパイプライン処理では、スクリプトを記述しているもののみ取り上げ)&#x2b07;&#xfe0f;</td></tr><tr><td colspan="2"><strong>Dropbox</strong>：Dropboxのローカルフォルダが全ての源流。私の場合、mmedia、pmediaという名のフォルダを設けている。この２つのフォルダを、各サーバーへコピーあるいは同期する。</td></tr><tr><td colspan="2"><s><strong>自宅サーバー</strong>：SynologyNASにWordPressサーバーを建てている。SynologyNASのCloudSyncを使いDropbox経由で同期している。</s></td></tr><tr><td colspan="2"><strong>Xserver(WordPress)</strong>：SynologyNASからXserverへ、ShellScriptのrsyncにより送り込んでいる。毎分処理。</td></tr><tr><td colspan="2"><strong>pCloud</strong>：pCloudDriveの同期機能を使い、ローカルフォルダとpCloudのPublic Folder内のフォルダと同期する。</td></tr></tbody></table></figure>



<ul class="wp-block-list">
<li><strong>ファイルパス変更記録ファイル</strong>を保持する<br>（Macで変更前ファイルパスと変更後ファイルパスを記録して、Spreadsheetを更新する）</li>



<li>ライブラリ登録の時、これを照合して、配信用URL（例：https://imakat.com/rd.php?id=Abcd0123.png）に紐づくパスやファイル名を<strong>最新のものに置き換えたJSONファイルを生成</strong>する。</li>
</ul>



<p>こうすることで、仮にファイル構成やファイル名が変わっても、<strong>配信</strong><strong>URL</strong><strong>自体は変更せずに運用を継続できる</strong>ようになります。</p>



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



<h3 class="wp-block-heading"><strong>３. </strong>メディアライブラリ更新のアルゴリズム</h3>



<p>メディアライブラリの更新の判断は以下のようになっています。まず最初にファイルパスが変更されたかどうかが基軸になります。ファイルパスが同じで、Dropboxリンクが変更されている場合は、メディアライブラリに登録するDropboxリンクも変更されます。Dropboxリンクが同じでファイルパスが変更されている場合は、メディアライブラリに登録するファイルパスも変更されます。この仕組みにより、ファイルパスやフォルダ名が変更されても、配信用URLは不変で運用ができるようになっています。</p>



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



<h3 class="wp-block-heading"><strong>４. </strong>まとめ</h3>



<ul class="wp-block-list">
<li><strong>トークンリンク方式</strong>は運用が安定していますが、Dropboxへの依存が避けられず、サービス継続性にリスクがあります。</li>



<li><strong>直リンク方式</strong>は柔軟性が高く、複数の配信拠点を設けることが可能ですが、リンク切れ対策が不可欠です。</li>



<li><strong>リンク切れを防ぐ仕組み</strong>として、ファイルの変更監視と配信用URLの動的更新が効果的です。</li>
</ul>



<p><strong>第５章〜終わりに、では、「動画パッケージの作り方」</strong>についてご紹介します。<br></p>



<p>&#x27a1; <a href="https://imakat.com/2025/04/29/26044/" 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">25984</post-id>	</item>
		<item>
		<title>第３章：YouTubeなど（大手）に依存しないで配信する～複数の再生サーバーを切り替える仕組み～</title>
		<link>https://imakat.com/2025/04/25/25930/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Thu, 24 Apr 2025 20:19:59 +0000</pubDate>
				<category><![CDATA[マイライブラリ]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[ストリーミング]]></category>
		<category><![CDATA[直リンク]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[トークンリンク]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[Webホスティング]]></category>
		<category><![CDATA[メディアアセット]]></category>
		<category><![CDATA[NFC]]></category>
		<category><![CDATA[RFC]]></category>
		<category><![CDATA[識別子]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=25930</guid>

					<description><![CDATA[メディアライブラリを作ろう 本章では、YouTubeやTikTokなどの大手拡散型プラットフォームを使用せず、自前の仕組みで動画やメディアを配信する方法について深掘りしていきます。つまり、クラウド時代の“ハンドメイド配信 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>メディアライブラリを作ろう</p>



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



<p>本章では、YouTubeやTikTokなどの大手拡散型プラットフォームを使用せず、自前の仕組みで動画やメディアを配信する方法について深掘りしていきます。つまり、クラウド時代の“ハンドメイド配信”を実現するための枠組みです。</p>



<h3 class="wp-block-heading"><strong>1. 特定の大手に依存しないということの意味</strong></h3>



<p>YouTubeなどの大手は、確かに拡散力や安定性に優れていますが、同時にそのプラットフォームの規約や方針変更に大きく左右されます。広告挿入やアルゴリズムによる露出制限など、制作者の意思とは無関係な制限が突然加わる可能性も否定できません。それからYouTubeやTikTokなど大手の多くは、少し手を加えるだけで簡単に他人の動画を切り抜いて転用できる、AI自動生成物がその真偽を検証されることなく配信される、そうした緩さがあるため、どうしても信用性は低く、オモチャや娯楽の道具として一段低く扱われやすいことがあります。</p>



<p>私が目指すのは、小規模ながらも自由度が高く、そして制作者の意思で完結できる配信手段です。ただし、ここには大きな課題もあります。それは“<strong>小さな仕組みほど不安定で消えやすい。小さな会社ほど資金が乏しくすぐ倒産する。</strong>”という現実です。</p>



<p>この課題は、製造業におけるサプライチェーンの問題と非常によく似ています。特定の国や工場に依存しすぎると、何らかの外的要因で供給が止まるリスクがあります。そうでないにしても関税のように異常な高コストになるリスクがあります。同様に、配信インフラが一箇所に依存していると、そのサービスが終了した瞬間にすべての再生が止まってしまいます。</p>



<p>だからこそ必要なのが「<strong>複数の小規模の再生サーバーを柔軟に切り替える仕組み</strong>」です。</p>



<h3 class="wp-block-heading"><strong>2. 再生URLの設計と意味</strong></h3>



<p>私が使っている再生URLの構造は以下の通りです：</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>https://imakat.com/rd.php?id=Abcd0123.png</strong></td></tr></tbody></table></figure>



<ul class="wp-block-list">
<li>imakat.com は私の管理しているドメイン名です。</li>



<li>rd.php は再生用の振り分けスクリプトです。</li>



<li>Abcd0123.png の部分が、一意の識別子になっています。</li>
</ul>



<p>この識別子には<strong>ランダムな8文字の大小英文字数字</strong>を使い、あえて<strong>拡張子（.png や .mp4 など）を付けた形式</strong>を採用しています。<br>これにより、URLだけを見てもおおよそのファイル種別が判断できるため、運用や整理の際にとても便利です。</p>



<p>よく見かける「拡張子なしのランダム識別子」も確かにセキュリティ的な利点はありますが、その一方でファイル内容の把握や管理は困難になります。</p>



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



<p>WordPressサーバー側で、phpスクリプトによって、選択された再生サーバー番号に合わせて、送り込んだJSONファイルとの照合を行ったりエンコード後のURLを生成するなどの作業を行っています。</p>



<h4 class="wp-block-heading">直リンク方式の場合は、ファイルパスのエンコードが必要</h4>



<p>直リンク方式(ファイルパス方式)の場合に、ファイルパスのエンコードが必要になりますが、ややこしい問題は、そのエンコードの方式が、サーバー会社によって異なる点です。各社が提供したエンコード後URLと、自分がファイルパスに基づく直リンクをエンコードしたURL、両者を比較して、それが一致するエンコード方式を使用することです。一致しないと、「ファイルが見つかりません」となり再生されません。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>mmediaまたはpmedia以下のファイルパス</td><td>/mmedia/id45_メディアライブラリ_はじめに/250411_メディアライブラリ_はじめに.mp4</td></tr><tr><td><strong>TypeA</strong><br>[NFC.RFC3986 URL encoding]方式によるエンコードをすると&#x27a1;&#xfe0f;</td><td>/mmedia/id45_%E3%83%A1%E3%83%86%E3%82%99%E3%82%A3%E3%82%A2%E3%83%A9%E3%82%A4%E3%83%95%E3%82%99%E3%83%A9%E3%83%AA_%E3%81%AF%E3%81%97%E3%82%99%E3%82%81%E3%81%AB/250411_%E3%83%A1%E3%83%86%E3%82%99%E3%82%A3%E3%82%A2%E3%83%A9%E3%82%A4%E3%83%95%E3%82%99%E3%83%A9%E3%83%AA_%E3%81%AF%E3%81%97%E3%82%99%E3%82%81%E3%81%AB.mp4</td></tr><tr><td><strong>TypeB</strong><br>[NFC,部分エンコード(ブラウザ互換型)&nbsp;]によるエンコードをすると&#x27a1;&#xfe0f;</td><td>/mmedia/id45_%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA_%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB/250411_%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA_%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB.mp4</td></tr><tr><td></td><td>&#x2b06;&#xfe0f;<strong>TypeAとTypeBとでは、よく見ると、あちこち、かなり文字が異なっています。</strong></td></tr></tbody></table></figure>



<p><br>この問題を除けば、直リンク方式の方が、今回行っているような構築は、はるかに簡単に済みます。<br>ただし現実には、直リンク方式を提供するクラウドストレージの会社は非常に少なくなり、pCloudはそのうちの1社です。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td colspan="2">WordPress(Xserver)内のURL再生が可能な状態にする(rd.php、再生用振り分けスクリプト)</td></tr><tr><td colspan="2"><a href="https://imakat.com/?pubtxt=マイライブラリXserverのrdphp_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>



<p>結局、そのクラウドストレージがその内部にWebサーバーを建てること(Webホスティング)を許可しているかどうか、Webサーバーを建てることができれば、直リンク方式の開放ができる可能性が高いです。次章で深掘りしますが、残念ながら、例えば、Dropbox、Googleドライブ、iCloudドライブ、Oneドライブなど主要大手は、ストレージの中にWebサーバーを建てることができなくなっているわけです。その中で、Dropboxはraw=1により表示が可能、pCloudはパブリックフォルダにより表示が可能、と珍しい存在になっているわけです。</p>



<p>ただし、直リンク方式は、ファイルパスやファイル名を変更するとリンク切れを起こす、という致命的欠点があります。この欠点の克服方法を、別の章で紹介することにします。</p>



<h3 class="wp-block-heading"><strong>3. リンク提供とストリーミング再生の違い</strong></h3>



<p>再生URLは、<strong>動画や音声などのストリーミング再生、画像再生</strong>を行うための仕組みですが、<strong>ファイルの直接ダウンロードリンク</strong>としても応用可能です。たとえばExcelファイルの配布などにも対応できます。</p>



<p>ただし、<strong>再生</strong><strong>URL</strong><strong>をダウンロード専用の仕組みとして多用するのはおすすめしません</strong>。本来の目的はストリーミングにあるため、無理に使い方を広げすぎると運用が複雑になってしまいます。</p>



<h3 class="wp-block-heading"><strong>4. </strong>再生までの処理フロー</h3>



<p>以下が再生までの処理フローです：</p>



<ol class="wp-block-list">
<li>ユーザーがブラウザやメールクライアントなどから再生URLにアクセスする</li>



<li>rd.php が呼び出され、該当する識別子（例：Abcd0123.png）に紐づくサーバーを判定する</li>



<li>メディアライブラリアプリ(AppSheet)にて選ばれた再生サーバー（Dropbox、Xserver、pCloudなど）へ転送される</li>



<li>ストリーミング再生が開始される</li>
</ol>



<p>これにより、<strong>複数の配信先を動的に切り替えられる柔軟な配信構造</strong>が実現します。たとえ1つのサーバーに不具合が起きても、他のサーバーで代替再生が可能になります。</p>



<h3 class="wp-block-heading">次回予告：</h3>



<p><strong>第４章では、「リンク切れを防ぐ仕組みほか」</strong>についてご紹介します。<br></p>



<p>&#x27a1; <a href="https://imakat.com/2025/04/26/25984/" 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">25930</post-id>	</item>
		<item>
		<title>第2章「メディアライブラリへの登録〜パイプライン処理〜」</title>
		<link>https://imakat.com/2025/04/08/25796/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Tue, 08 Apr 2025 02:02:58 +0000</pubDate>
				<category><![CDATA[マイライブラリ]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[MAM]]></category>
		<category><![CDATA[メディアアセット]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=25796</guid>

					<description><![CDATA[メディアライブラリを作ろう ポイント解説： 作成するスクリプトは、結構、分量があります。ChatGPTを使い、ゆっくり進めるのがいいです。以下のスクリプトをChatGPTへコピペして、（１）「このスクリプトの解説をしてく [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>メディアライブラリを作ろう</p>


<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=46" 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=kmelubbx.png" playsinline preload="metadata" style="width:100%;height:auto;">  <source src="https://imakat.com/rd.php?id=p5ZFXLqv.mp4" type="video/mp4">  <track src="https://imakat.com/rd.php?id=enPvHIg9.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:00">00:00:00</a>)  〜メディアライブラリを作ろう〜<br>
(<a href="#" class="imk-cue" data-seek="0:18">00:00:18</a>)  メディア用ライブラリですね。そのパイプライン処理をですね。やってみたいと思います。<br>
(<a href="#" class="imk-cue" data-seek="0:30">00:00:30</a>)  まずこの画面にですね。画像が入っているフォルダーがあります。<br>
(<a href="#" class="imk-cue" data-seek="0:37">00:00:37</a>)  1つこれはChatGPTで作った画像ですけれどもこの画像ですね。pmediaフォルダにコピーします。<br>
(<a href="#" class="imk-cue" data-seek="0:54">00:00:54</a>)  実はもうコピーしてあります。このように「鳥の群れ」のですね。写真が入ってます。<br>
(<a href="#" class="imk-cue" data-seek="1:05">00:01:05</a>)  次にこのファイルの上でメディアライブラリ作成を行います。<br>
(<a href="#" class="imk-cue" data-seek="1:12">00:01:12</a>)  データがPythonによってGASへ送られます。<br>
(<a href="#" class="imk-cue" data-seek="1:24">00:01:24</a>)  ちょっと待つのですがGASへ送られました。GASにデータが正常に送信されました。<br>
(<a href="#" class="imk-cue" data-seek="1:37">00:01:37</a>)  OKを押します。<br>
(<a href="#" class="imk-cue" data-seek="1:40">00:01:40</a>)  この状態ですとどうなってるかと言うとSpreadsheetを持ってきます。<br>
(<a href="#" class="imk-cue" data-seek="1:50">00:01:50</a>)  そうするとですね。Spreadsheetの1番上段にですね。もう、ChatGPT今のファイルですね。それが登録されてます。<br>
(<a href="#" class="imk-cue" data-seek="2:06">00:02:06</a>)  同時にこれに登録されていれば当然なんですが、<br>
(<a href="#" class="imk-cue" data-seek="2:14">00:02:14</a>)  メディアライブラリですね。<br>
(<a href="#" class="imk-cue" data-seek="2:16">00:02:16</a>)  AppSheetで作ったメディア用ライブラリの先頭にもですね。ChatGPTの画像が入ってきます。<br>
(<a href="#" class="imk-cue" data-seek="2:34">00:02:34</a>)  これ今現在、処理が少し時間がかかるので、<br>
(<a href="#" class="imk-cue" data-seek="2:43">00:02:43</a>)  「エラー：指定されたIDのデータが見つかりません」となりますが、少し待ちます。<br>
(<a href="#" class="imk-cue" data-seek="2:51">00:02:51</a>)  どうでしょうか。はい再生URLから「鳥の群れ」の画像が表示されました。<br>
(<a href="#" class="imk-cue" data-seek="3:04">00:03:04</a>)  これは実はいくつかの再生サーバーに置いてあるんですけれども、<br>
(<a href="#" class="imk-cue" data-seek="3:11">00:03:11</a>)  Dropboxリンクからはこのように再生されます。<br>
(<a href="#" class="imk-cue" data-seek="3:18">00:03:18</a>)  それからもう一つWPエンコード後URL、これはWordPressサーバーですが、そこからもしっかり再生されます。<br>
(<a href="#" class="imk-cue" data-seek="3:32">00:03:32</a>)  いくつか再生サーバーがあるんですけれども、それを選択をするようになってまして、<br>
(<a href="#" class="imk-cue" data-seek="3:38">00:03:38</a>)  選択番号3っていうのはですね。このWordPressサーバーから引っ張ってくることになっています。<br>
(<a href="#" class="imk-cue" data-seek="3:50">00:03:50</a>)  これですね。この再生URLこれをクリックするとWordPressサーバーから引っ張ってくるようになっています。今3番を選んでますからですね。<br>
(<a href="#" class="imk-cue" data-seek="4:07">00:04:07</a>)  このような形で処理が行われます。　<br>
(<a href="#" class="imk-cue" data-seek="4:14">00:04:14</a>)  それでは次ですね。もう一つの改良点についてですね。説明します。<br>
(<a href="#" class="imk-cue" data-seek="4:22">00:04:22</a>)  今の1つのファイルを登録したわけですね。<br>
(<a href="#" class="imk-cue" data-seek="4:28">00:04:28</a>)  このChatGPTimage..pngを登録したわけですけれども、<br>
(<a href="#" class="imk-cue" data-seek="4:34">00:04:34</a>)  このChatGPTimage..と言う抽象的な名前ですと、何のことかわからんわけですね。<br>
(<a href="#" class="imk-cue" data-seek="4:42">00:04:42</a>)  それでファイル名の中に具体的な例えば何の映像だとかそういうことをですね。書いておいたほうがいいですよね。<br>
(<a href="#" class="imk-cue" data-seek="4:54">00:04:54</a>)  ファイルの名前を変えるわけです。その場合。<br>
(<a href="#" class="imk-cue" data-seek="5:00">00:05:00</a>)  名前を変えます。<br>
(<a href="#" class="imk-cue" data-seek="5:07">00:05:07</a>)  具体的には日付、これはですね。これは「鳥の群れ」とします。名前を変えました。<br>
(<a href="#" class="imk-cue" data-seek="5:33">00:05:33</a>)  そうするとですね。中で自動処理が進んでまして、<br>
(<a href="#" class="imk-cue" data-seek="5:41">00:05:41</a>)  名前を変更する前のファイルパスそれから名前を変更した後のファイルパスをデータとして保存してます。従ってそれで置き換えができるようになってます。<br>
(<a href="#" class="imk-cue" data-seek="5:56">00:05:56</a>)  例えば今、ここにあるファイルですけどもしばらく放置しておきます。<br>
(<a href="#" class="imk-cue" data-seek="6:09">00:06:09</a>)  実際、5分に1回の処理なんですが、ちょっと5分待つことにはなるんですが、<br>
(<a href="#" class="imk-cue" data-seek="6:17">00:06:17</a>)  何もしなくていいです<br>
(<a href="#" class="imk-cue" data-seek="6:20">00:06:20</a>)  そうするとここがですね変わってきますので、少々お待ちください。<br>
(<a href="#" class="imk-cue" data-seek="6:31">00:06:31</a>)  名前が変わりました「鳥の群れ」ですね。名前が変わってます。<br>
(<a href="#" class="imk-cue" data-seek="6:40">00:06:40</a>)  名前は変わりましたが再生URLの番号ですね。識別番号は変わってません。<br>
(<a href="#" class="imk-cue" data-seek="6:50">00:06:50</a>)  従って、実際このURLを使ってWordPressに記述したとしてもですね。全然それは変更しなくてもいいわけですね。<br>
(<a href="#" class="imk-cue" data-seek="7:05">00:07:05</a>)  こういったことが行えるようになってます。<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>



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



<p>作成するスクリプトは、結構、分量があります。ChatGPTを使い、ゆっくり進めるのがいいです。以下のスクリプトをChatGPTへコピペして、（１）「このスクリプトの解説をしてください」と、まず解説をしてもらう（２）その解説の中で、自分向けに修正する箇所を指摘して、スクリプトの記述を指示する、そのようなやり方が効率的です。表の右欄に、スクリプトをリンクします。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td colspan="2" style="background-color:#dddddd"><strong>パイプライン処理</strong>(画面入力をトリガーに、一品料理で一連の処理を行う)</td></tr><tr><td>&#x2b07;&#xfe0f;＜マイライブラリ画面入力＞<br>Finderで選択したファイルを処理し、対応するDropbox共有リンクを自動取得して送信スクリプトに渡すAppleScript。ファイルのパスや拡張子を取得し、日本語などを除去してDropbox形式のファイル名に整形。Python仮想環境のget_dropbox_link.pyでリンクを生成し、ファイル名の整合性を確認後、send_request.pyでリンク情報を送信。</td><td><a href="https://imakat.com/script_list/?pubtxt=マイライブラリ_画面入力_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><tr><td>&#x2b07;&#xfe0f;＜マイライブラリDropboxAPI認証リンク取得GAS通信＞<br>DropboxのOAuth認証設定、リンク自動取得、GASとの通信を行う3本のPythonスクリプト群。<br>①dropbox_auth_setup.pyはローカルHTTPサーバで認証コードを受け取り、Dropboxのアクセストークンとリフレッシュトークンを取得する。<br>②get_dropbox_link.pyはリフレッシュトークンを用いてDropbox APIに接続し、指定ローカルファイルの共有リンクを取得または生成し、dl=0をraw=1に変換して出力する。<br>③send_request.pyはAppleScriptから受け取ったDropboxリンクやファイル情報をGASのエンドポイントへJSON形式で送信し、更新処理を実行する。</td><td><a href="https://imakat.com/script_list/?pubtxt=マイライブラリ_dropboxAPI_Mac_GASデータ交換_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><tr><td>&#x2b07;&#xfe0f;<a rel="noopener" target="_blank" href="https://docs.google.com/drawings/d/1JgcOPS8GESxG34LDFSUE1i3CVe0PSM6sAyZrfqkV0cc/edit?usp=sharing">＜マイライブラリ生成更新処理＞<span class="fa fa-external-link external-icon anchor-icon"></span></a><br>mediaLibrary.gsは、Dropbox等のメディアファイル情報をF1シートで一元管理し、その変更を自動反映するGASです。ファイル名・パスから一意なwpidexを生成し、sb付き一時ファイル名や?v=付きURL、NFC差、連続スラッシュなどを正規化して突合します。doPostはmodeにより、ライブラリのフル再構築やvideoembed.jsonのみ更新、通常の作業行追加＋処理を切り替えます。processWorkingRecordはF3のパス変更履歴を反映しつつ、K=ADD行をADD2に更新し、JSON生成とライブラリ整理、pcloudidシートへの同期を行います。cleanMediaLibraryはDEL行や重複を除去し、更新日時で並べ替え、フラグをFALSEに戻します。videoembed関連は「動画パッケージ」シートから埋め込みHTMLを集約し、XserverのPHPにJSONをPOST送信します。</td><td><a href="https://imakat.com/script_list/?pubtxt=マイライブラリ_生成更新処理_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><tr><td>&#x2b07;&#xfe0f;＜メディアおよびJSONをXserverへ更新＞<br>Dropbox → Xserver 同期用のメインスクリプトは、pmedia・mmedia・meta_gd_wp_data を Homebrew 版 rsync で転送し、SSH鍵を自動ロードして毎分同期するよう LaunchAgent から実行される。ログは /tmp と $HOME/scripts/logs に記録される。<br>しかし rsync が残留してフリーズすることがあるため、毎日 3:30 に自動復旧スクリプトが動作し、pmedia/mmedia 関連の rsync プロセスを検出して kill し、メインの LaunchAgent（com.xxxxxxxxm1.sync_dropbox_xserver_m1）を unload/load し直して正常状態へ戻す仕組みとなっている。</td><td><a href="https://imakat.com/script_list/?pubtxt=メディアおよびJSONをXserverへ更新および自動復帰_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><tr><td>&#x2b07;&#xfe0f;＜配信サーバー切り替えリダイレクト処理＞<br>rd.phpは、指定されたidに対応するメディア情報をJSONから取得し、該当URLへ転送または中継出力するPHPスクリプト。txt・vtt・srtなど文字ファイルの場合は、文字化け防止のためサーバー側でUTF-8へ変換して直接配信する。Dropbox・Xserver・pCloudなど複数サーバーのURLを動的に切り替え、キャッシュ防止や診断表示（?diag=1）にも対応する。</td><td><a href="https://imakat.com/script_list/?pubtxt=マイライブラリXserverのrdphp_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>



<p></p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td colspan="2" style="background-color:#dddddd"><strong>バックグラウンド処理</strong>(常時監視する)</td></tr><tr><td colspan="2">＜ファイルパス変更処理＞<br>mmedia・pmedia フォルダを常時監視し、ファイルやフォルダの移動・リネーム（MOVED）を検出して記録する Python スクリプト。検出時には変更前・変更後パス、JST の更新時刻、更新フラグ TRUE を Google スプレッドシート（sheet1）へ追記し、その後シート全体を読み込んで (A,B) が同じ重複記録は「最も古いものだけ残す」形に正規化し、更新日時の降順で再整列して書き戻す。scripts_pub や .dropbox など特定パスは無視するフィルタを搭載。watchdog によりディレクトリを監視し続け、ログは ~/Library/Logs に記録。LaunchAgent（com.xxxxxxxx.filewatcher.plist）を用いて macOS 起動時に自動実行される構成となっている。</td></tr><tr><td colspan="2"><a href="https://imakat.com/script_list/?pubtxt=ファイルパス変更処理_gasからpython移行_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>



<p>上の処理はMacを使った処理ですが、ChatGPTの分析では、Windowsへの移植には、以下が変更点になります。Mac、Windowsで共通して使えるGAS、AppSheetを中心に据える作り方がベターと言えます。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td colspan="3"><strong>Windowsへの変更点</strong></td></tr><tr><td><strong>処理</strong></td><td><strong>Mac</strong></td><td><strong>Windoowsでの代替</strong></td></tr><tr><td>GUI自動処理</td><td>AppleScript</td><td>PowerShell or Python GUI</td></tr><tr><td>クリップボード</td><td><code>the clipboard</code></td><td><code>pyperclip</code>&nbsp;(Python)</td></tr><tr><td>パス処理</td><td>POSIXパス</td><td><code>os.path</code>&nbsp;(Python)</td></tr><tr><td>sed/basename</td><td>shellコマンド</td><td>Pythonの標準ライブラリ</td></tr><tr><td>GAS通信</td><td><code>requests.post</code></td><td>そのままOK</td></tr><tr><td>フォルダ監視</td><td>shell + find/comm</td><td>PowerShell +&nbsp;<code>Compare-Object</code></td></tr><tr><td>自動同期</td><td>rsync</td><td>robocopy / WinSCP</td></tr><tr><td>タスク自動実行</td><td>Automator or cron</td><td>Windowsタスクスケジューラ</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">次回予告：</h3>



<p><strong>第3章では、「<strong>YouTube（大手）に依存しないで配信する</strong>」</strong>についてご紹介します。<br></p>



<p>&#x27a1; <a href="https://imakat.com/2025/04/25/25930/" target="_blank">第3章を読む</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">25796</post-id>	</item>
		<item>
		<title>第1章「メディアライブラリ構築の目的と背景」</title>
		<link>https://imakat.com/2025/04/03/25693/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Thu, 03 Apr 2025 11:45:00 +0000</pubDate>
				<category><![CDATA[マイライブラリ]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[MAM]]></category>
		<category><![CDATA[メディアアセット]]></category>
		<category><![CDATA[Mac]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=25693</guid>

					<description><![CDATA[メディアライブラリを作ろう はじめに： いまの時代、動画はたくさん出回っています。でも、その動画を作るために使った素材――たとえば写真や音声、字幕や説明文など――は、紐づいて保存されているでしょうか。 最近の動画編集ツー [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>メディアライブラリを作ろう</p>


<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=45" 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=SNebSNKN.png" playsinline preload="metadata" style="width:100%;height:auto;">  <source src="https://imakat.com/rd.php?id=b2WjRm31.mp4" type="video/mp4">  <track src="https://imakat.com/rd.php?id=06LGXJgR.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:00">00:00:00</a>)  メディアライブラリを作ろう〜はじめに〜<br>
(<a href="#" class="imk-cue" data-seek="0:19">00:00:19</a>)  メディアライブラリを作ろうというテーマで、解説を始めます。どちらかというと、地味なテーマで、かっこよくも、美しくもないです。<br>
(<a href="#" class="imk-cue" data-seek="0:36">00:00:36</a>)  しかし、例えば、動画の配信は、ほとんどの方が、YouTubeやTikTokを使っていますね。<br>
(<a href="#" class="imk-cue" data-seek="0:48">00:00:48</a>)  やたら再生回数、いいね、登録を求められて、そういうやり方は、自分にとっては風呂敷を広げ過ぎです。 <br>
(<a href="#" class="imk-cue" data-seek="1:03">00:01:03</a>)  そんなことよりも、地味にITやパソコンをやってるマイナーな層に、配信できればそれでいいと思っています。<br>
(<a href="#" class="imk-cue" data-seek="1:16">00:01:16</a>)  だから、YouTubeを使わないで、自分のホームページ、Web、ブログから動画や画像を配信することができるようにしたいわけです。<br>
(<a href="#" class="imk-cue" data-seek="1:32">00:01:32</a>)  コマーシャルなど入らないように配信したいです。<br>
(<a href="#" class="imk-cue" data-seek="1:39">00:01:39</a>)  そう望まれる方は、このシリーズが役に立つのではと思います。<br>
(<a href="#" class="imk-cue" data-seek="1:45">00:01:45</a>)  私は、WordPressを使いますが、DNSが設定できてWeb配信ができれば、他のやり方でも、構造的には同じことかと思います。<br>
(<a href="#" class="imk-cue" data-seek="2:04">00:02:04</a>)  そういった普通の作業方法は、自分のパソコンで動画や画像の作成をして、それをレンタルサーバーへアップロードする、この流れが正しいです。<br>
(<a href="#" class="imk-cue" data-seek="2:20">00:02:20</a>)  ところで、動画や画像などはメディアアセットと呼びますが、メディアアセットは、最近はDropboxなどのクラウドストレージで作業をして保管をしていることも多くなっています。<br>
(<a href="#" class="imk-cue" data-seek="2:43">00:02:43</a>)  クラウドストレージは、そのままリンクを共有できるものが多く、それをブログに貼り付けて公開する方法も、一般化しています。<br>
(<a href="#" class="imk-cue" data-seek="2:57">00:02:57</a>)  ただし気掛かりな点は、クラウドストレージもレンタルサーバーも、いつ撤退するか分からない点です。<br>
(<a href="#" class="imk-cue" data-seek="3:09">00:03:09</a>)  その対処は、完璧な方法はありませんが、ひと所に依存しない、複数使えるようにしておくことだ、と考えます。<br>
(<a href="#" class="imk-cue" data-seek="3:25">00:03:25</a>)  今回のような、ハンドメイドの配信システムを持つメリットは、やはり、いつでも自由に手直しができることです。<br>
(<a href="#" class="imk-cue" data-seek="3:37">00:03:37</a>)  結局、趣味の内容をブログにするので、記事も動画画像も頻繁に手直ししますから。<br>
(<a href="#" class="imk-cue" data-seek="3:47">00:03:47</a>)  私の作ったものは、メディアライブラリと動画パッケージ、動画ライブラリですが、頻繁に手直しする人のための道具です。<br>
(<a href="#" class="imk-cue" data-seek="4:02">00:04:02</a>)  図を見ていただきたいですが、<br>
(<a href="#" class="imk-cue" data-seek="4:05">00:04:05</a>)  動画や画像といったメディアアセットは、中には大容量の、500MBを超えるようなものもあり、入れ物が必要になります。<br>
(<a href="#" class="imk-cue" data-seek="4:22">00:04:22</a>)  サーバーに保管します。<br>
(<a href="#" class="imk-cue" data-seek="4:28">00:04:28</a>)  しかし、そのメディアアセットをマネジメントする、管理するための情報は、私の場合、Googleドライブ内のSpreadsheetで行っています。<br>
(<a href="#" class="imk-cue" data-seek="4:44">00:04:44</a>)  アセット自体の管理と、運用するためのメタ情報の管理は、分離することができます。<br>
(<a href="#" class="imk-cue" data-seek="4:55">00:04:55</a>)  図書館の本の場合は、貸し出すためのサービスが、本を貸し出すための窓口が各図書館に必要になりますが、　<br>
(<a href="#" class="imk-cue" data-seek="5:08">00:05:08</a>)  動画や画像といったメディア情報は、その置き場所ごとに管理の仕組みを設ける必要はなくて、<br>
(<a href="#" class="imk-cue" data-seek="5:20">00:05:20</a>)  一括してまとめてコントロールすることができます。<br>
(<a href="#" class="imk-cue" data-seek="5:27">00:05:27</a>)  アセット自体の管理と、運用するためのメタ情報の管理は、分離することができます。<br>
(<a href="#" class="imk-cue" data-seek="5:39">00:05:39</a>)  ただし、メタ情報のメンテナンスは瞬時にできますが、アセットの移動は、何分かかかる場合もあります。そこにはどうしてもタイムラグが生じます。<br>
(<a href="#" class="imk-cue" data-seek="6:02">00:06:02</a>)  ブログは修正されたが、動画や画像がまだ届いていない、といったタイムラグもどうしても生じます。<br>
(<a href="#" class="imk-cue" data-seek="6:14">00:06:14</a>)  それでは、次は、実際に、Macの画面操作を見ていきます。<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>



<h3 class="wp-block-heading">はじめに：</h3>



<p>いまの時代、動画はたくさん出回っています。<br>でも、その動画を作るために使った素材――たとえば写真や音声、字幕や説明文など――は、紐づいて保存されているでしょうか。</p>



<p>最近の動画編集ツールは、ブラウザから手軽に使えるものが多くなっています。<br>素材をいくつかアップして、簡単な操作で動画が完成する。便利で楽しい仕組みになっています。<br>そして完成した動画は、そのままYouTube、TikTokなどの配信サイトにアップされ、世界中に届けられます。</p>



<h4 class="wp-block-heading">プロセスは、隠された箱の中</h4>



<p>時代は生成AIですね。</p>



<p>でも、その一方で、完成した動画は、「どうやって作られたのか」、「どんな素材で作られたか」は、作成者は全く分からない、原型を留めないほどに、変形させられるものも多々あります。こうなった時、それが私の作品、所有者は私、と言われても、すっと腑に落ちません。</p>



<p></p>



<h3 class="wp-block-heading">出発点は「整理整頓」：</h3>



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



<p>さて、これからの時代、動画などのメディアコンテンツの作り方は、どんな考え方に傾いていくでしょうか。</p>



<h4 class="wp-block-heading">適当なものを放り込んで、ボタンを押したらヒョッコリ出来ただけ</h4>



<p>ひとつは、「完成した動画があれば、素材がなにだったか、原型がどうだったかは、気にしない。レシピはアプリ会社が用意したものから選ぶだけでいい。」という考え方。早い安い美味い、インスタント即決重視。</p>



<p>もうひとつは、「動画の元になった素材や、その作り方の記録も残っていて、<strong>所有権は私のもの</strong>であり再加工も私はできる」という考え方。音楽制作や文芸で著作権の大切さを感じた人にある感覚でしょうか。</p>



<p>前者は、何が原因でどういう条件でこの結果となったかが分からないので、何を大事に残したらいいかが分からない。素材軽視、意外性重視、偶然好み、結果だけあればいい。完成物だけ持って飛び出していく人。やりっぱなしで、でも元ネタはここにあるはず、となると捨てられず、家はゴミ屋敷。</p>



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



<p>いいえ全員そうだとは言いませんが、概してそう。</p>



<p>小さい頃から言われ続けてきた整理整頓は、やはり重要です。</p>



<p>完成した動画だけでなく、それを作るまでに使った素材や字幕、説明なども、あとから見返せるようにしたい。<br>再利用や別の作品への展開にも役立ちます。</p>



<p></p>



<h3 class="wp-block-heading">「フォルダ整理」の次に「ライブラリ」生成へ：</h3>



<p>このシリーズでは、**「メディアライブラリ」**を、メディアコンテンツを作成保存するDropbox（私の場合)を出発点にして、身近な道具を活用しながら、どう作っていくか、これまで数回に渡り掲載してきたライブラリ生成のまとめとして、ご紹介していきます。</p>



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



<p>メディアライブラリとは、図書館がサービスとして本を貸し出してくれるように、そのメディアコンテンツを配信してくれるところです。しかし図書館といえど世の中のすべての書物を扱えるわけではありません。日本の図書館には、ほとんどが日本語の書物です。同じように、ここでいうメディアライブラリは、「自分が所有している配信可能なコンテンツのうち、配信する予定のあるものを、配信できる状態にスタンバイさせたもの」となります。</p>



<p>ここから先は、メディアコンテンツを流通させる手法を取り扱っていくので、メディアの中身そのものというより、メディアの属性やメタ情報に焦点を当てていきます。そしてメディアの総体をメディアアセットと呼んでいくことにします。<br><br>(※アセットとは、一般的には「資産」の意味です。「情報」に対して「情報資産」と呼ぶと、まあ意味は何となく分かりますが、しかしこの「情報資産」は、質量を持たず、瞬時に無限に複製移動出来る不思議な存在です。)</p>



<p>ですから、包含関係で言うと、「自分の所有するメディアアセット⊇配信可能なアセット⊇配信する予定のあるアセット⊇配信できる状態にスタンバイしたアセット」となります。</p>



<p>具体的に私の例で言うと、</p>



<p>(A)自分の所有するメディアアセット(様々なデバイス):<br>iPhoneやiPadに保存した画像やイラスト、動画、音声など、FinalCutPro、Cubase、図形描画、ドキュメントなどで加工中あるいは完成したものなど。<br><br>(B)配信可能なアセット(私の場合はDropbox):<br>(A)の内で、他者にわたることを前提とした、合法なコンテンツ</p>



<p>(C)配信する予定のあるアセット(私の場合は、Dropbox、Xserver、自宅サーバー、pCloud、Vimeo、YouTube):<br>(B)の内で、配信にマッチするように調整を済ませたコンテンツ</p>



<p>(D)配信できる状態にスタンバイしたアセット(私の場合は、Dropbox、Xserver、自宅サーバー、pCloud、Vimeo、YouTube):<br>(C)の内で、共有URLを持って、ランチャー（発射台）にセットされたアセット<br><br>※(C)と(D)の違いは、ステータス（公開、非公開）の違い。</p>



<p><br>以上のようになります。<br>このうち、(B)について、Dropboxの中にフォルダ(mmedia pmedia)を設定しています。このフォルダの整理以降が、今シリーズの対象になります。<br><br></p>



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



<h3 class="wp-block-heading">メディアライブラリは商社の本社機能のようなもの：</h3>



<p>図書館とメディアライブラリの違いを考えてみます。<br>一言でいって、サービス部門の設置場所が、違ってきます。図書館は書籍を受け渡しするためサービス部門は各図書館内に必要です。書籍は質量がありますから。<br>それに対して、メディアライブラリは、動画、画像、テキストといった、質量がなく即座に複製移動できる、情報アセットを受け渡しするサービス部門です。従って、メディアライブラリは、アセットが複数の場所に存在していても、「何がどこにあるか」というメタ情報(台帳のようなもの)があればいいだけです。それは一ヶ所あれば十分です。</p>



<p>メディアライブラリはGoogleドライブを使っています。Googleドライブには、動画、画像、テキストといったアセット自体は置きません。置くのは、そのアセットの特性や特徴を記録したアセット情報(台帳)だけです。メタデータだけです。<br>またGoogleドライブには、GASやAppSheetなどの指示命令機能がそなわっています。いわば、商社の本社機能と言っていいです。</p>



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



<h3 class="wp-block-heading">このシリーズで目指すもの：</h3>



<p>このシリーズでは、DropboxやWordPressサーバーなど、<strong>すでに持っている道具、標準装備されているものをうまく使って</strong>、<br><br>誰でもできる「メディアライブラリのかたち」を提案していきます。</p>



<h3 class="wp-block-heading">こんな方におすすめ：</h3>



<p>この連載は、私自身が実際にメディアライブラリを作ってきた経験をもとに、<br>できるだけわかりやすく紹介していくことを目指しています。</p>



<p>パソコンは<strong>&nbsp;Mac</strong>&nbsp;を使用しており、<br>そのために&nbsp;<strong>AppleScript&nbsp;</strong>や&nbsp;<strong>Automator</strong>&nbsp;など、Mac特有の言語やアプリを使う場面も出てきます。</p>



<p>でも、どれも難しいプログラミングではなく、<br>「ちょっとした工夫で整理がしやすくなる」という発想に近い内容です。</p>



<ul class="wp-block-list">
<li><strong>動画配信やメディア配信を、YouTubeに類するような大手配信サービスに依存したくない方、ひと所に依存したくない方</strong></li>



<li><strong>動画や画像を頻繁に手直ししたい方</strong></li>



<li><strong>共有URLの提供を、自分として一本化したい方</strong></li>



<li><strong>メディアコンテンツの作成からメディアアセットの管理を、一貫して行いたい方</strong></li>



<li><strong>そうした<a rel="noopener" target="_blank" href="https://ja.wikipedia.org/wiki/デジタル資産管理">メディアアセット管理システム(MAM)<span class="fa fa-external-link external-icon anchor-icon"></span></a>を、あまりお金を掛けないで、ハンドメイドで小規模に実現したい方</strong></li>
</ul>



<p>そんな方にとって、きっとヒントになるシリーズになると思います。</p>



<p><br><br>次回からは、実際の構造や工夫について、図や例をまじえながらお伝えしていきます。</p>



<h3 class="wp-block-heading">準備するもの：</h3>



<p>Mac、Dropbox、Googleドライブ、AppSheet、AppleScript、Python、GAS、ShellScript<br>です。DropboxおよびGoogleドライブは最下位の有料版で十分。</p>



<h3 class="wp-block-heading">次回予告：</h3>



<p><strong>第2章では、「メディアライブラリへの登録〜パイプライン処理〜</strong>」についてご紹介します。<br></p>



<p>&#x27a1; <a href="https://imakat.com/2025/04/08/25796/">第2章を読む</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>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">25693</post-id>	</item>
		<item>
		<title>【WordPress】ヘッダーの背景画像を曜日で変える</title>
		<link>https://imakat.com/2024/11/07/24072/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Wed, 06 Nov 2024 23:24:53 +0000</pubDate>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[自宅サーバー]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=24072</guid>

					<description><![CDATA[今回の小改善ですが、おそらく、プラグインの中に出来るものがあるとは思いますが、割と簡単なので、ChatGPTに依頼しながらphpで作成することにします。 WordPressのテーマに無料のCocoonを使用していますが、 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>今回の小改善ですが、おそらく、プラグインの中に出来るものがあるとは思いますが、割と簡単なので、ChatGPTに依頼しながらphpで作成することにします。</p>



<p>WordPressのテーマに無料の<a rel="noopener" target="_blank" href="https://wp-cocoon.com">Cocoon<span class="fa fa-external-link external-icon anchor-icon"></span></a>を使用していますが、使い続けさせていただき感謝を申し上げる次第ですが、とても分かりやすくできているので初めての人でもすぐに馴染めます。子テーマへは、自分なりのカスタマイズも行えるようになっており中級者にも満足いけるものと思います。</p>



<p>ページのデザインには、たくさんの着替えが選べるようになっています。</p>



<p>ブログで一番目立つ場所は、やはりヘッダーだろうと思います。このヘッダーには、ロゴやキャッチフレーズが自由に差し替えられます。ヘッダーの背景画像も差し替えが出来ます。</p>



<p>そこで思ったのは、このヘッダーの背景画像が自動的に差し替えが出来たらいい、というか、手元の、Macやパソコンの画像ファイルを書き換えたら、そのままWordPressの更新がされたらラク、そう考えました。ちなみに、キャッチフレーズも日替わりはどうかと考えてみましたが、SEOに悪影響がありそうなのと、そもそもあまり面白味がないので、やめました。</p>



<figure class="wp-block-image size-large"><a href="https://imakat.com/rd.php?id=vepBJ8fH.png" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=vepBJ8fH.png" alt=""/></a><figcaption class="wp-element-caption">imakat_header_imageフォルダに各曜日の画像.pngを保存する。</figcaption></figure>



<h4 class="wp-block-heading">3つの更新方法</h4>



<div class="wp-block-cocoon-blocks-sticky-box blank-box block-box sticky">
<p><strong>No１　＜単純に、外部WordPressサーバーへFTP更新する＞</strong>XserverにあるWordPressサーバーへ、FTPで更新する。Hazelでimakat_header_imageフォルダ(フォルダ名は任意)を監視して、更新されたら、Transmit5アプリでFTPを起動させて、Xserverへ更新することも可能。phpの構造は３方法とも同じで、URLが異なるのみ。URLは、XserverにあるWordPressサーバーに登録したhead-insert.phpの中に書き込む。<br><strong>画像のURL：https://imakat.com/&#8230;&#8230;/imakat_header_image/monday_image.png</strong></p>
</div>



<div class="wp-block-cocoon-blocks-sticky-box blank-box block-box sticky">
<p><strong>No２　＜自宅WordPressサーバーのフォルダを更新する＞</strong>自宅のSynologyNASにあるWordPressサーバーのimakat_header_imageフォルダをCloudSyncでDropbox同期する。Macのimakat_header_imageフォルダをDropbox同期する。Mac上で曜日別画像.pngの更新を行うと自宅WordPressサーバーも更新される。phpの構造は３方法とも同じで、URLが異なるのみ。URLは、XserverにあるWordPressサーバーに登録したhead-insert.phpの中に書き込む。<br><strong>画像のURL：https://imakat.synology.me/&#8230;&#8230;./imakat_header_image/monday_image.png</strong></p>
</div>



<div class="wp-block-cocoon-blocks-sticky-box blank-box block-box sticky">
<p><strong>No３　＜Dropboxの画像ファイルを更新する＞</strong>フォルダの中に作ったimakat_header_imageフォルダの中の曜日別画像.pngのDropboxリンクを取得する。phpの構造は３方法とも同じで、URLが異なるのみ。但しこのDropboxのURLは共有トークンリンクURLで非常に長いランダムな文字列になっている。URLは、XserverにあるWordPressサーバーに登録したhead-insert.phpの中に書き込む。<br><strong>画像のURL：https://www.dropbox.com/scl/fi/xxxxx&#8230;xxxxxx/monday_image.png?rlkey=yyyy&#8230;..yyyyy&amp;raw=1</strong></p>
</div>



<p>以上ですが、No１はオーソドックスな方法で、間違いは少ないです。No２は、自宅サーバーがある場合は、Macのフォルダに画像ファイルを更新するだけで、Web配信まで連動していくのでシンプルです。No３はMacのDropboxフォルダにある画像ファイルを更新するだけで、Web配信まで連動していくので、一見、シンプルですがしかし画像のURLは複雑なトークンリンクになっています。</p>



<h4 class="wp-block-heading">No３のデメリット</h4>



<p>No３のデメリットを言います。No１とNo２は、URLからフォルダ階層が明示されるので迷子にならないですが、No３はURLは暗号化された文字列でありフォルダ階層も分かりません。従って、URLとファイルパスをコンビにしてどこかに記録しておかないと迷子になります。上書きは結構、頻繁に行うことになると思います。もし、<strong>上書きに失敗して新規にリンク取得となると、また、head-insert.phpを書き換える必要が生じます。</strong>これは起こり得ることだと思います。</p>



<h4 class="wp-block-heading">当面は、No２を利用</h4>



<p>No３を別の寸評をすると「壊れやすい華奢」。No１とNo２は「少々乱暴でも壊れない」。</p>



<p>私としては、ブログは、読みこみ許可、書き込み禁止で公開するのを基本と考えていまして、ファイルの所在位置が分かってしまうことは問題ではありません。それゆえ２を選択することにします。</p>



<h4 class="wp-block-heading">具体的な設定</h4>



<p> URLで共有できるメディアサーバーがあれば、その中にxxxxx_header_imageフォルダを設定します。パーミッションを、管理者以外は読み込みのみ、URLを知っている人全員可、に設定します。</p>



<p>日本時間での曜日の変更になります。</p>



<p>画像は、pngでもjpgでも問題ありません。画像のサイズは、ヘッダーのデザインによりますが、0.5MB程度に調整するのがいいと思います。<br></p>



<h5 class="wp-block-heading">header-insert.phpへの記述</h5>



<p>Cocoonの場合は、テーマCocoon child→tmp-user→head-insert.phpになります。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>Cocoonの場合は、テーマCocoon child→tmp-user→head-insert.phpになります。</td></tr><tr><td><a href="" target="_blank"></a><a href="" target="_blank"></a><a href="https://imakat.com/wp-content/pmedia/scripts_pub/ヘッダー画像の毎日更新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>



<p>以上です。<br><br></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">24072</post-id>	</item>
		<item>
		<title>Dropboxの動画をWordPressへ貼り付ける方法</title>
		<link>https://imakat.com/2024/01/22/18942/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Mon, 22 Jan 2024 01:19:00 +0000</pubDate>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[vimeo]]></category>
		<category><![CDATA[自宅サーバー]]></category>
		<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=18942</guid>

					<description><![CDATA[2024.5.20変更：www.dropbox.comはそのままで、dl=0→raw=1へ変更しました。2024.5.5変更：Dropboxリンクの書き換え方法を、www.dropbox.com→dl.dropbox.c [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>2024.5.20変更：www.dropbox.comはそのままで、dl=0→raw=1へ変更しました。<br>2024.5.5変更：<br>Dropboxリンクの書き換え方法を、www.dropbox.com→dl.dropbox.com、dl=0→raw=1へ変更しました。</p>



<hr class="wp-block-separator has-text-color has-cyan-bluish-gray-color has-alpha-channel-opacity has-cyan-bluish-gray-background-color has-background is-style-wide"/>



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



<p>改めて、災害時の損失を抑え復旧を速やかに行うことが大切と感じています。自宅サーバーを今すぐ撤去するつもりはありませんが、自宅サーバーに依存しない方向、自宅サーバーは選択肢の一つにする方向、そちらへ舵を切りたいと思います。動画再生方法のいくつかの選択肢をテストする中で、その選択肢を更に使いやすくする方法を作ってみます。なお、Google単独は、GoogleドライブからWordPressプレーヤーへ動画と字幕を同期させて引き込む方法は、基本的には困難なようですので、対象から除きました。</p>



<h6 class="wp-block-heading">No1　Vimeo単独</h6>



<p>VimeoはYouTubeと同様にトランスコードされてストリーミング再生されるので、停滞が非常に少ないです。<strong>Vimeoは、動画の、まるごと差し替えがOK、何回でも上書きアップロードができます</strong>。</p>



<figure class="wp-block-flexible-table-block-table is-content-justification-left is-scroll-on-pc is-scroll-on-mobile"><table class=""><tbody><tr><td></td><td style="text-align:center">動画ファイル</td><td style="text-align:center">字幕ファイル</td><td style="text-align:center">初期画面ファイル</td></tr><tr><td>Vimeo</td><td style="text-align:center">◎</td><td style="text-align:center">◎<br>(Vimeoサイトに<br>アップロードする)</td><td style="text-align:center">◎<br>(動画からショットするか、<br>Vimeoにアップロードする)</td></tr><tr><td>Dropbox</td><td style="text-align:center"></td><td style="text-align:center"></td><td style="text-align:center"></td></tr><tr><td>Google</td><td style="text-align:center"></td><td style="text-align:center"></td><td style="text-align:center"></td></tr><tr><td>自宅サーバー</td><td style="text-align:center"></td><td style="text-align:center"></td><td style="text-align:center"></td></tr><tr><td>外部サーバー<br>(Xserver)</td><td style="text-align:center"></td><td style="text-align:center"></td><td style="text-align:center"></td></tr></tbody></table></figure>



<p><span class="red"><s>注：動画の中で、書き換え方法を、dl=0→raw=1としていますが、www.dropbox.com→dl.dropbox.com dl=0→raw＝1へ変更しています。</s></span></p>



<p style="font-size: 14px;">
  <a href="https://imakat.com/vm5?movid=905195687" target="_blank">
   動画を別ページで表示します(ここをクリック)。
  </a>
<div style="position:relative;"><iframe src="https://player.vimeo.com/video/905195687?
texttrack=ja&#038;loop=0&#038;title=0&#038;byline=0&#038;muted=0&#038;pip=1&#038;portrait=0&#038;autopause=0&#038;" style="position:absolute;top:0;left:0;width:100%;height:100%;" frameborder="0" allow="autoplay;fullscreen" allowfullscreen=""></iframe></div><script src="https://player.vimeo.com/api/player.js"></script><details><summary>字幕一覧(クリック)</summary> <p>
1) Dropboxの動画をWordPressに貼り付ける<br>
2) はい。それでは今からDropboxにある動画を、WordPress へ貼り付ける方法について紹介します。<br>
3) まず結論からですが、Vimeoの代用にDropboxを使うことにします。　<br>
4) 私の場合は元ネタの動画だとか写真はですね、ほぼ全部Dropboxの中にありますので、<br>
5) それを、簡単に加工して送信できればいいわけです。<br>
6) 2つ目に、Dropboxですけれども、そのスピードはもちろん、その動画配信サービスの、<br>
7) YouTubeだとかVimeoには劣りますけども、<br>
8) 自宅サーバーよりは速いです。<br>
9) 3番目に、同じクラウドサービスに、Google ドライブがあります。<br>
10) Googleドライブを使う方法を調べたが、<br>
11) 字幕ファイルの同期の方法がよくわかりません。<br>
12) GoogleとしてはYouTubeを利用すればいいと考えているのかなと感じます。　<br>
13) そういった意味で、私にとってはですね、<br>
14) このDropbox対Googleについては、<br>
15) Dropboxが使いやすそうです。<br>
16) それでは、使うための準備を進めます。<br>
17) まず、Dropboxリンクは、そのままWordPressへ貼り付けても動かないです。<br>
18) 手直しする必要があります。<br>
19) Dropboxリンクですけれども、<br>
20) この以下のこの長いURLになってます。<br>
21) 2023年ですね、12月からですね、この、rlkeyというものが加わってとても長くなりました。<br>
22) この2行目からのこの部分ですね、<br>
23) まあ、過剰な負荷だとか、安全対策が強化されたようです。<br>
24) これに伴って、2023年12月以降は、WordPress用の貼り付けコードも変わってきています。<br>
25) 残念ながらこのままでは、WordPressは再生できません。<br>
26) この赤い部分ですね、dl=0の部分を、raw=1で置き換えます。<br>
27) すなわち、以下のような形です。<br>
28) これを作成します。<br>
29) これをですね、マウスの操作だけで行うクイックアクションを作成します。AppleScriptを使います。<br>
30) 以下のように作るのですが、<br>
31) このスクリプトについては、ブログへ添付しますのでご覧ください。<br>
32) このスクリプトについては、ブログへ添付しますのでご覧ください。<br>
33) それで、作ったクイックアクションを実行して、置き換えが正しいかどうか確認します。<br>
34) 動きをご覧ください。<br>
35) 確認するテスト画像ですね、これです。<br>
36) その上で右クリックをして、Dropboxリンクをコピーします。<br>
37) それをメモにペーストします。<br>
38) ペースト、<br>
39) でその上で、左クリックを3回、<br>
40) で、右クリックをして、<br>
41) サービスの中から、DropboxリンクをWordPress用に変換する、を選びます。<br>
42) コピーされます。OK。<br>
43) でそれを、<br>
44) メモにペーストします。<br>
45) こういった出来上がりになります。<br>
46) 変えられた部分は、dl=0が、<br>
47) raw=1に変わっています。<br>
48) それではこの出来上がったものをクリックして確認してみましょう。<br>
49) 確かに画像が出ます。<br>
50) これだけでも、ですね、<br>
51) このクイックアクション、汎用に使えるんですけれども、<br>
52) もう一つAppleScriptのアプリケーションを組み合わせて、WordPressへの動画貼り付けコードを生成したいと思います。<br>
53) 3番目、<br>
54) WordPressへの動画貼り付けコードを生成します。<br>
55) これはまた同じく、AppleScriptのスクリプトですけれども、スクリプトエディターで作ります。<br>
56) 以下のような内容です。この内容もブログへ添付しますので、<br>
57) コピーしてお使いください。<br>
58) その結果のですね、<br>
59) アプリケーションの実行の様子をご覧ください。<br>
60) 最初にアプリケーションを起動させます。<br>
61) それで、<br>
62) 開始画面の画像URLを入れてください、ということで、最初にその画像ファイル、<br>
63) を選び、その上で右クリックして、Dropboxリンクをコピーします。<br>
64) それを、ダイアログボックスのところにペーストします。<br>
65) その上で、左クリック3回、右クリック、サービスから、<br>
66) 変換アクション、<br>
67) コピーがされたらそれを、<br>
68) ボックスに貼り付けます。<br>
69) OK。<br>
70) 次に、<br>
71) 動画本体のURLを、<br>
72) 変換します。<br>
73) 目的の、<br>
74) ファイルを選びます。<br>
75) どれだ、<br>
76) はい、右クリックして、Dropboxリンクのコピーして、<br>
77) それを、ダイアログボックスにペーストして、<br>
78) 左クリック3回、<br>
79) 右クリック、<br>
80) サービスの中からアクションを選び、変換したものを、<br>
81) 置き換えます。<br>
82) OK。<br>
83) 次に、字幕ファイルのURLです。<br>
84) 探します。<br>
85) vttファイルです。<br>
86) 右クリックして、<br>
87) リンクをコピーして、<br>
88) ダイアログボックスにペーストします。左クリック3回、右クリック、<br>
89) サービスの中からアクションを起動して、<br>
90) 出来上がったコードを、<br>
91) 貼り付けます。<br>
92) OK。<br>
93) 最後に動画の説明を記入します。<br>
94) 何入れてもいいんですが、先頭の文字に小文字の不等号カッコ、これはダメです。<br>
95) で、出来上がったものがこういった形でですね、コードが出来上がります。<br>
96) OK。<br>
97) クリップボードにコピーされますのでそれをWordPressへペーストします。<br>
98) カスタムHTMLコードへ、<br>
99) ペーストします。プレビューを押します。<br>
100) 起動してみます。<br>
101) ちゃんと動いてますね、<br>
102) はい、正しくできています。<br>
103) それでは以上で、Dropboxにある動画を、WordPressへ貼り付ける方法の説明を終わります。<br>
104) ありがとうございました。<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>




<h6 class="wp-block-heading">No2　Dropbox単独</h6>



<p>Dropboxは、ブログを補足するための短い簡潔なビデオが適しています。ニッチに役立つことが目的なので、集中アクセスは殆どないと想定しますが、一般向けの内容の場合はVimeoを使います。Dropboxの再生のスムーズさは、WiFi環境であれば、少々待ち時間はありますが、問題なく視聴できると思います。但しスマホで4Gセルラーでの視聴は、時間帯によっては困難かも知れません。特に昼休み。仕事場でWiFiや有線LANでパソコンを使っていた人が、昼休みになると一斉にスマホを使い出すので、昼休みは困難かも知れません。この動画は476MBと大きいサイズです。<strong style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); white-space: normal;">更新方法は、MacにあるDropboxにリンクしたローカルファイルを上書き保存するだけです</strong><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-family: -webkit-standard; font-size: medium; white-space: normal;">。</span></p>



<figure class="wp-block-flexible-table-block-table is-content-justification-left is-scroll-on-pc is-scroll-on-mobile"><table class=""><tbody><tr><td></td><td style="text-align:center">動画ファイル</td><td style="text-align:center">字幕ファイル</td><td style="text-align:center">初期画面ファイル</td></tr><tr><td>Vimeo</td><td style="text-align:center"></td><td style="text-align:center"></td><td style="text-align:center"></td></tr><tr><td>Dropbox</td><td style="text-align:center">○<br><span class="red"><span class="fz-12px">dl=0 → raw=1</span><br><span class="fz-12px"><s>www.dropbox.com →dl.dropbox.com</s></span></span></td><td style="text-align:center"></td><td style="text-align:center">◎<br><span class="red"><span class="fz-12px">dl=0 → raw=1</span><br><span class="fz-12px"><s>www.dropbox.com →dl.dropbox.com</s></span></span></td></tr><tr><td>Google</td><td style="text-align:center"></td><td style="text-align:center"></td><td style="text-align:center"></td></tr><tr><td>自宅サーバー</td><td style="text-align:center"></td><td style="text-align:center"></td><td style="text-align:center"></td></tr><tr><td>外部サーバー(Xserver)</td><td style="text-align:center"></td><td style="text-align:center">◎<br><span class="fz-12px">直接アップロード</span></td><td style="text-align:center"></td></tr></tbody></table><figcaption>字幕ファイルは、WordPressブログを発信しているサーバー内に置く。</figcaption></figure>



<p><span class="red"><s>注：動画の中で、書き換え方法を、dl=0→raw=1としていますが、www.dropbox.com→dl.dropbox.com dl=0→raw＝1へ変更しています。</s></span></p>



<figure class="wp-block-video aligncenter">
<video controls 
poster="https://www.dropbox.com/scl/fi/4isbb7bfnk7w9vnczilcu/240122_Dropbox.png?rlkey=rxkgwu4apmg07dmkc0h5vptn8&#038;raw=1"
src="https://www.dropbox.com/scl/fi/oewlvtdcqeqp7d9w777t9/2401221_Dropbox-WordPress.mp4?rlkey=7mstp5fm6rgrtrgsvlun0vex5&#038;raw=1" 
playsinline="">
<track default=""
src="https://imakat.com/wp-content/uploads/gd_wp_data/vttdata/15_240122_dropbox_timeadded.vtt" 
label="日本語" srclang="ja" kind="subtitles">
</video>
<figcaption>
</figcaption>
</figure>



<details translate="yes"><summary translate="yes">字幕一覧(クリック)</summary> <p translate="yes">
(00:00:00) Dropboxの動画をWordPressに貼り付ける<br>
(00:00:04) はい。それでは今からDropboxにある動画を、WordPress へ貼り付ける方法について紹介します。<br>
(00:00:17) まず結論からですが、Vimeoの代用にDropboxを使うことにします。　<br>
(00:00:26) 私の場合は元ネタの動画だとか写真はですね、 ほぼ全部Dropboxの中にありますので、<br>
(00:00:35) それを、簡単に加工して送信できればいいわけです。<br>
(00:00:43) 2つ目に、Dropboxですけれども、そのスピードはもちろん、その動画配信サービスの、 <br>
(00:00:50) YouTubeだとかVimeoには劣りますけども、<br>
(00:00:55) 自宅サーバーよりは速いです。<br>
(00:01:01) 3番目に、同じクラウドサービスに、Google ドライブがあります。<br>
(00:01:07) Googleドライブを使う方法を調べたが、<br>
(00:01:13) 字幕ファイルの同期の方法がよくわかりません。<br>
(00:01:17) GoogleとしてはYouTubeを利用すればいいと考えているのかなと感じます。　<br>
(00:01:26) そういった意味で、私にとってはですね、<br>
(00:01:30) このDropbox対Googleについては、<br>
(00:01:36) Dropboxが使いやすそうです。<br>
(00:01:41) それでは、使うための準備を進めます。<br>
(00:01:50) まず、Dropboxリンクは、そのままWordPressへ貼り付けても動かないです。 <br>
(00:01:59) 手直しする必要があります。<br>
(00:02:08) Dropboxリンクですけれども、<br>
(00:02:13) この以下のこの長いURLになってます。<br>
(00:02:19) 2023年ですね、12月からですね、この、rlkeyというものが加わってとても長くなりました。<br>
(00:02:29) この2行目からのこの部分ですね、<br>
(00:02:36) まあ、過剰な負荷だとか、安全対策が強化されたようです。<br>
(00:02:43) これに伴って、2023年12月以降は、WordPress用の貼り付けコードも変わってきています。<br>
(00:02:54) 残念ながらこのままでは、WordPressは再生できません。<br>
(00:03:01) この赤い部分ですね、dl=0の部分を、raw=1で置き換えます。<br>
(00:03:14) すなわち、以下のような形です。<br>
(00:03:22) これを作成します。<br>
(00:03:31) これをですね、マウスの操作だけで行うクイックアクションを作成します。AppleScriptを使います。<br>
(00:03:43) 以下のように作るのですが、<br>
(00:03:46) このスクリプトについては、ブログへ添付しますのでご覧ください。<br>
(00:03:52) このスクリプトについては、ブログへ添付しますのでご覧ください。<br>
(00:04:00) それで、作ったクイックアクションを実行して、置き換えが正しいかどうか確認します。<br>
(00:04:09) 動きをご覧ください。<br>
(00:04:16) 確認するテスト画像ですね、これです。<br>
(00:04:22) その上で右クリックをして、Dropboxリンクをコピーします。<br>
(00:04:31) それをメモにペーストします。 <br>
(00:04:36) ペースト、<br>
(00:04:38) でその上で、左クリックを3回、<br>
(00:04:44) で、右クリックをして、<br>
(00:04:48) サービスの中から、DropboxリンクをWordPress用に変換する、を選びます。<br>
(00:04:59) コピーされます。OK。<br>
(00:05:05) でそれを、<br>
(00:05:07) メモにペーストします。<br>
(00:05:10) こういった出来上がりになります。<br>
(00:05:14) 変えられた部分は、dl=0が、<br>
(00:05:23) raw=1に変わっています。<br>
(00:05:29) それではこの出来上がったものをクリックして確認してみましょう。<br>
(00:05:39) 確かに画像が出ます。<br>
(00:05:48) これだけでも、ですね、<br>
(00:05:53) このクイックアクション、汎用に使えるんですけれども、<br>
(00:05:57) もう一つAppleScriptのアプリケーションを組み合わせて、WordPressへの動画貼り付けコードを生成したいと思います。<br>
(00:06:12) 3番目、<br>
(00:06:14) WordPressへの動画貼り付けコードを生成します。<br>
(00:06:20) これはまた同じく、AppleScriptのスクリプトですけれども、スクリプトエディターで作ります。<br>
(00:06:29) 以下のような内容です。この内容もブログへ添付しますので、<br>
(00:06:40) コピーしてお使いください。<br>
(00:06:44) その結果のですね、<br>
(00:06:47) アプリケーションの実行の様子をご覧ください。<br>
(00:06:55) 最初にアプリケーションを起動させます。<br>
(00:07:11) それで、<br>
(00:07:15) 開始画面の画像URLを入れてください、ということで、最初にその画像ファイル、<br>
(00:07:26) を選び、その上で右クリックして、Dropboxリンクをコピーします。<br>
(00:07:33) それを、ダイアログボックスのところにペーストします。<br>
(00:07:40) その上で、左クリック3回、右クリック、サービスから、<br>
(00:07:48) 変換アクション、<br>
(00:07:53) コピーがされたらそれを、<br>
(00:07:57) ボックスに貼り付けます。<br>
(00:08:00) OK。<br>
(00:08:03) 次に、<br>
(00:08:06) 動画本体のURLを、<br>
(00:08:10) 変換します。<br>
(00:08:14) 目的の、<br>
(00:08:19) ファイルを選びます。<br>
(00:08:23) どれだ、<br>
(00:08:31) はい、右クリックして、Dropboxリンクのコピーして、<br>
(00:08:39) それを、ダイアログボックスにペーストして、<br>
(00:08:46) 左クリック3回、<br>
(00:08:51) 右クリック、<br>
(00:08:53) サービスの中からアクションを選び、変換したものを、<br>
(00:09:02) 置き換えます。<br>
(00:09:05) OK。<br>
(00:09:09) 次に、字幕ファイルのURLです。<br>
(00:09:14) 探します。<br>
(00:09:18) vttファイルです。 <br>
(00:09:23) 右クリックして、<br>
(00:09:26) リンクをコピーして、<br>
(00:09:29) ダイアログボックスにペーストします。左クリック3回、右クリック、<br>
(00:09:38) サービスの中からアクションを起動して、<br>
(00:09:42) 出来上がったコードを、<br>
(00:09:46) 貼り付けます。<br>
(00:09:48) OK。<br>
(00:09:51) 最後に動画の説明を記入します。<br>
(00:09:55) 何入れてもいいんですが、先頭の文字に小文字の不等号カッコ、これはダメです。<br>
(00:10:05) で、出来上がったものがこういった形でですね、コードが出来上がります。<br>
(00:10:23) OK。<br>
(00:10:25) クリップボードにコピーされますのでそれをWordPressへペーストします。<br>
(00:10:33) カスタムHTMLコードへ、<br>
(00:10:37) ペーストします。プレビューを押します。<br>
(00:10:47) 起動してみます。<br>
(00:10:55) ちゃんと動いてますね、<br>
(00:11:14) はい、正しくできています。<br>
(00:11:19) それでは以上で、Dropboxにある動画を、WordPressへ貼り付ける方法の説明を終わります。<br>
(00:11:29) ありがとうございました。<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>




<h6 class="wp-block-heading">No3　自宅単独</h6>



<figure class="wp-block-flexible-table-block-table is-content-justification-left is-scroll-on-pc is-scroll-on-mobile"><table class=""><tbody><tr><td></td><td style="text-align:center">動画ファイル</td><td style="text-align:center">字幕ファイル</td><td style="text-align:center">初期画面ファイル</td></tr><tr><td>Vimeo</td><td style="text-align:center"></td><td style="text-align:center"></td><td style="text-align:center"></td></tr><tr><td>Dropbox</td><td style="text-align:center"></td><td style="text-align:center"></td><td style="text-align:center"></td></tr><tr><td>Google</td><td style="text-align:center"></td><td style="text-align:center"></td><td style="text-align:center"></td></tr><tr><td>自宅サーバー</td><td style="text-align:center">○</td><td style="text-align:center"></td><td style="text-align:center">◎</td></tr><tr><td>外部サーバー<br>(Xserver)</td><td style="text-align:center"></td><td style="text-align:center">◎<br><span class="fz-12px">直接アップロード</span></td><td style="text-align:center"></td></tr></tbody></table><figcaption>字幕ファイルは、WordPressブログを発信しているサーバー内に置く。</figcaption></figure>



<p>Dropboxより非力です。過去の投稿で紹介してきた通り、一般には、476MBという大きい動画を扱うのは無理クリですが、あえて掲載しました。WiFi環境で、高速度なら、視聴できるかも知れません。場合によってはDropboxよりサクサク動くこともあります。<strong>更新方法は、MacにあるDropboxにリンクしたローカルファイル(実はWordPressフォルダとも同期させている)を上書き保存するだけです</strong>。</p>



<p><span class="red"><s>注：動画の中で、書き換え方法を、dl=0→raw=1としていますが、www.dropbox.com→dl.dropbox.com dl=0→raw＝1へ変更しています。</s></span></p>



<figure class="wp-block-video aligncenter">
<video controls
poster="https://imakat.synology.me/wp-content/pmedia/240122_Dropbox貼り付け.png"
src="https://imakat.synology.me/wp-content/mmedia/2401221_Dropboxの動画をWordPressへ貼り付ける.mp4" 
playsinline="">
<track default="" 
src="https://imakat.com/wp-content/uploads/gd_wp_data/vttdata/15_240122_dropbox_timeadded.vtt" 
label="日本語" srclang="ja" kind="subtitles">
</video>
<figcaption>
</figcaption>
</figure>



<details translate="yes"><summary translate="yes">字幕一覧(クリック)</summary> <p translate="yes">
(00:00:00) Dropboxの動画をWordPressに貼り付ける<br>
(00:00:04) はい。それでは今からDropboxにある動画を、WordPress へ貼り付ける方法について紹介します。<br>
(00:00:17) まず結論からですが、Vimeoの代用にDropboxを使うことにします。　<br>
(00:00:26) 私の場合は元ネタの動画だとか写真はですね、 ほぼ全部Dropboxの中にありますので、<br>
(00:00:35) それを、簡単に加工して送信できればいいわけです。<br>
(00:00:43) 2つ目に、Dropboxですけれども、そのスピードはもちろん、その動画配信サービスの、 <br>
(00:00:50) YouTubeだとかVimeoには劣りますけども、<br>
(00:00:55) 自宅サーバーよりは速いです。<br>
(00:01:01) 3番目に、同じクラウドサービスに、Google ドライブがあります。<br>
(00:01:07) Googleドライブを使う方法を調べたが、<br>
(00:01:13) 字幕ファイルの同期の方法がよくわかりません。<br>
(00:01:17) GoogleとしてはYouTubeを利用すればいいと考えているのかなと感じます。　<br>
(00:01:26) そういった意味で、私にとってはですね、<br>
(00:01:30) このDropbox対Googleについては、<br>
(00:01:36) Dropboxが使いやすそうです。<br>
(00:01:41) それでは、使うための準備を進めます。<br>
(00:01:50) まず、Dropboxリンクは、そのままWordPressへ貼り付けても動かないです。 <br>
(00:01:59) 手直しする必要があります。<br>
(00:02:08) Dropboxリンクですけれども、<br>
(00:02:13) この以下のこの長いURLになってます。<br>
(00:02:19) 2023年ですね、12月からですね、この、rlkeyというものが加わってとても長くなりました。<br>
(00:02:29) この2行目からのこの部分ですね、<br>
(00:02:36) まあ、過剰な負荷だとか、安全対策が強化されたようです。<br>
(00:02:43) これに伴って、2023年12月以降は、WordPress用の貼り付けコードも変わってきています。<br>
(00:02:54) 残念ながらこのままでは、WordPressは再生できません。<br>
(00:03:01) この赤い部分ですね、dl=0の部分を、raw=1で置き換えます。<br>
(00:03:14) すなわち、以下のような形です。<br>
(00:03:22) これを作成します。<br>
(00:03:31) これをですね、マウスの操作だけで行うクイックアクションを作成します。AppleScriptを使います。<br>
(00:03:43) 以下のように作るのですが、<br>
(00:03:46) このスクリプトについては、ブログへ添付しますのでご覧ください。<br>
(00:03:52) このスクリプトについては、ブログへ添付しますのでご覧ください。<br>
(00:04:00) それで、作ったクイックアクションを実行して、置き換えが正しいかどうか確認します。<br>
(00:04:09) 動きをご覧ください。<br>
(00:04:16) 確認するテスト画像ですね、これです。<br>
(00:04:22) その上で右クリックをして、Dropboxリンクをコピーします。<br>
(00:04:31) それをメモにペーストします。 <br>
(00:04:36) ペースト、<br>
(00:04:38) でその上で、左クリックを3回、<br>
(00:04:44) で、右クリックをして、<br>
(00:04:48) サービスの中から、DropboxリンクをWordPress用に変換する、を選びます。<br>
(00:04:59) コピーされます。OK。<br>
(00:05:05) でそれを、<br>
(00:05:07) メモにペーストします。<br>
(00:05:10) こういった出来上がりになります。<br>
(00:05:14) 変えられた部分は、dl=0が、<br>
(00:05:23) raw=1に変わっています。<br>
(00:05:29) それではこの出来上がったものをクリックして確認してみましょう。<br>
(00:05:39) 確かに画像が出ます。<br>
(00:05:48) これだけでも、ですね、<br>
(00:05:53) このクイックアクション、汎用に使えるんですけれども、<br>
(00:05:57) もう一つAppleScriptのアプリケーションを組み合わせて、WordPressへの動画貼り付けコードを生成したいと思います。<br>
(00:06:12) 3番目、<br>
(00:06:14) WordPressへの動画貼り付けコードを生成します。<br>
(00:06:20) これはまた同じく、AppleScriptのスクリプトですけれども、スクリプトエディターで作ります。<br>
(00:06:29) 以下のような内容です。この内容もブログへ添付しますので、<br>
(00:06:40) コピーしてお使いください。<br>
(00:06:44) その結果のですね、<br>
(00:06:47) アプリケーションの実行の様子をご覧ください。<br>
(00:06:55) 最初にアプリケーションを起動させます。<br>
(00:07:11) それで、<br>
(00:07:15) 開始画面の画像URLを入れてください、ということで、最初にその画像ファイル、<br>
(00:07:26) を選び、その上で右クリックして、Dropboxリンクをコピーします。<br>
(00:07:33) それを、ダイアログボックスのところにペーストします。<br>
(00:07:40) その上で、左クリック3回、右クリック、サービスから、<br>
(00:07:48) 変換アクション、<br>
(00:07:53) コピーがされたらそれを、<br>
(00:07:57) ボックスに貼り付けます。<br>
(00:08:00) OK。<br>
(00:08:03) 次に、<br>
(00:08:06) 動画本体のURLを、<br>
(00:08:10) 変換します。<br>
(00:08:14) 目的の、<br>
(00:08:19) ファイルを選びます。<br>
(00:08:23) どれだ、<br>
(00:08:31) はい、右クリックして、Dropboxリンクのコピーして、<br>
(00:08:39) それを、ダイアログボックスにペーストして、<br>
(00:08:46) 左クリック3回、<br>
(00:08:51) 右クリック、<br>
(00:08:53) サービスの中からアクションを選び、変換したものを、<br>
(00:09:02) 置き換えます。<br>
(00:09:05) OK。<br>
(00:09:09) 次に、字幕ファイルのURLです。<br>
(00:09:14) 探します。<br>
(00:09:18) vttファイルです。 <br>
(00:09:23) 右クリックして、<br>
(00:09:26) リンクをコピーして、<br>
(00:09:29) ダイアログボックスにペーストします。左クリック3回、右クリック、<br>
(00:09:38) サービスの中からアクションを起動して、<br>
(00:09:42) 出来上がったコードを、<br>
(00:09:46) 貼り付けます。<br>
(00:09:48) OK。<br>
(00:09:51) 最後に動画の説明を記入します。<br>
(00:09:55) 何入れてもいいんですが、先頭の文字に小文字の不等号カッコ、これはダメです。<br>
(00:10:05) で、出来上がったものがこういった形でですね、コードが出来上がります。<br>
(00:10:23) OK。<br>
(00:10:25) クリップボードにコピーされますのでそれをWordPressへペーストします。<br>
(00:10:33) カスタムHTMLコードへ、<br>
(00:10:37) ペーストします。プレビューを押します。<br>
(00:10:47) 起動してみます。<br>
(00:10:55) ちゃんと動いてますね、<br>
(00:11:14) はい、正しくできています。<br>
(00:11:19) それでは以上で、Dropboxにある動画を、WordPressへ貼り付ける方法の説明を終わります。<br>
(00:11:29) ありがとうございました。<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>




<p>No1~No3と比較してきましたが、現在、安定度に優れるのはNo1のVimeoが第１位、No2のDropbox単独が第2位です。扱い易さは、圧倒的にNo3の自宅単独です。実はこの3つ以外にも、Dropbox(動画、字幕) と自宅(初期画面)、Dropbox(動画、字幕) とGoogleフォト(初期画面)、Dropbox(動画、字幕) と外部(初期画面)についてテストをしましたが、今一つ不安定なことと操作が複雑になることから割愛しました。<br>しかし、今回、改めて考察するキッカケになった災害リスク。これを考えると、自宅のWebサーバーに比重を置くのは問題といえるでしょう。</p>



<p>従って、今回、<strong><span class="marker">「No2 Dropbox単独を採用</span></strong>していきます。10分未満の簡単編集でマニアックなものはDropbox、ファイルが重そうな10分以上あるいは一般向け配信のものはVimeoという使い分けをイメージしています。さあどうかな。</p>



<a href="https://imakat.com/ds5?drid=15" target="_blank">
    <img decoding="async" src="https://docs.google.com/drawings/d/e/2PACX-1vSYLNcifORpgWlD9fvrov_8o5NoHmlSoIiXejp8tHOdNiLL-OT8ld2iUsaCSfC_KHCo2fsa7aVvN-JH/pub?w=960&amp;h=720" alt="Google図形描画">
</a>



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



<h4 class="wp-block-heading">１　動画の中に登場するAppleScriptの紹介</h4>



<p>（１）Dropboxの共有リンクをWordPress貼り付け用に変換するクイックアクションのAppleScriptは、以下です。</p>



<p>コード変換の方法は、<br><strong><br><span class="fz-18px"><span class="marker-red">URLの記述の中の </span></span></strong></p>



<p><strong><span class="fz-18px"><span class="marker-red"><s>&#8220;www.dropbox.com&#8221; を&#8221;dl.dropbox.com&#8221;へ置き換える。</s></span></span></strong></p>



<p><strong><span class="fz-18px"><span class="marker-red">&#8220;dl=0&#8221; を&#8221;raw=1&#8243;へ置き換える。</span></span></strong></p>



<p>を使っています。なお、拡張子に関係なく扱えています。</p>



<p id="link1"> <strong><span class="marker">DropboxのURLを変換するAppleスクリプト</span></strong></p>



<p>「AppleScriptを実行」を挿入</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>-- DropboxのURLを変換するスクリプト

-- ３−１　ベースとなるDropboxの共有URLを一時的に保管する。
set baseURL to the clipboard
set tempURL to &quot;&quot;

-- 共有URLが存在するか確認
if baseURL is not equal to &quot;&quot; then
	
	-- ３−1　クリップボードの結果をtempURLへ置き換える。
	set tempURL to baseURL
	
	-- ３−２　URLの記述の中の &quot;www.dropbox.com&quot; を &quot;dl.dropbox.com&quot; へ置き換える。
	-- set tempURL to replaceText(&quot;www.dropbox.com&quot;, &quot;dl.dropbox.com&quot;, baseURL)
	
	-- ３−３　URLの記述の中の &quot;dl=0&quot; を&quot;raw=1&quot;へ置き換える。
	set tempURL to replaceText(&quot;dl=0&quot;, &quot;raw=1&quot;, tempURL)
	
	-- ３−４　クリップボードに保管する。「クリップボードにWordPress貼り付け用URLをコピーしました。」と表示する。
	set the clipboard to tempURL
	display dialog &quot;クリップボードにWordPress貼り付け用URLをコピーしました。&quot;
else
	display dialog &quot;共有URLが見つかりません。&quot;
end if

-- 文字列中の指定されたテキストを置き換える関数
on replaceText(find, replace, sourceText)
	set text item delimiters to find
	set sourceText to text items of sourceText
	set text item delimiters to replace
	set sourceText to sourceText as text
	set text item delimiters to &quot;&quot;
	return sourceText
end replaceText</code></pre></div>



<p id="link2">（２）<span class="marker"><strong>WordPress動画貼り付けコード生成用アプリ</strong></span>のAppleScriptは以下です。</p>



<pre class="wp-block-code"><code>-- スクリプトのテンプレート
set scriptTemplate to "&lt;figure class=\"wp-block-video aligncenter\"&gt;
&lt;video controls
poster=\"%poster%\"
src=\"%video%\" 
playsinline=\"\"&gt;
&lt;track default=\"\" 
src=\"%subtitles%\" 
label=\"日本語\" srclang=\"ja\" kind=\"subtitles\"&gt;
&lt;/video&gt;
&lt;figcaption&gt;%videoDescription%
&lt;/figcaption&gt;
&lt;/figure&gt;
&#091;dynamic_external_html url=\"%subtitle_list%\"]"

-- ダイアログでユーザーに入力を求める
set posterURL to text returned of (display dialog "&lt;WordPress動画貼り付けコードを生成&gt; 開始画面の画像のURLを入力してください(省略可)。" default answer "")
set videoURL to text returned of (display dialog "&lt;WordPress動画貼り付けコードを生成&gt; 動画本体のURLを入力してください(省略可)。" default answer "")
set subtitlesURL to text returned of (display dialog "&lt;WordPress動画貼り付けコードを生成&gt; 字幕ファイルのURLを入力してください(省略可)。" default answer "")
set videoDescription to text returned of (display dialog "&lt;WordPress動画貼り付けコードを生成&gt; 動画の説明を記入ください(省略可)。※先頭の文字に小文字の&lt; &gt;は不可。" default answer "")
set subtitleListURL to text returned of (display dialog "&lt;WordPress動画貼り付けコードを生成&gt; 字幕一覧のURLを入力してください(省略可)。" default answer "")

-- スクリプトのテンプレートをユーザーの入力で置き換える
set customHTML to scriptTemplate
set customHTML to my replaceText(customHTML, "%poster%", posterURL)
set customHTML to my replaceText(customHTML, "%video%", videoURL)
set customHTML to my replaceText(customHTML, "%subtitles%", subtitlesURL)
set customHTML to my replaceText(customHTML, "%videoDescription%", videoDescription)
set customHTML to my replaceText(customHTML, "%subtitle_list%", subtitleListURL)

-- 置換用の関数
on replaceText(originalText, searchString, replacementString)
	set AppleScript's text item delimiters to searchString
	set textItems to text items of originalText
	set AppleScript's text item delimiters to replacementString
	set replacedText to textItems as text
	set AppleScript's text item delimiters to ""
	return replacedText
end replaceText

-- 結果を表示
display dialog customHTML

-- 結果をクリップボードにコピー
set the clipboard to customHTML
display dialog "この内容をクリップボードにコピーしました。"</code></pre>



<p>なお、後日、字幕一覧のデータの投稿内引き込みを追加しました。WordPressのfunction.phpへ以下を追加ください。</p>



<pre class="wp-block-code"><code>&lt;?php
// 外部テキストを取得する関数
function fetch_dynamic_external_html_content($atts) {
    // ショートコードの引数を定義
    $attributes = shortcode_atts(array(
        'url' =&gt; '' // URLを指定する
    ), $atts);

    $url = $attributes&#091;'url'];
    
    // URLが指定されていない場合の処理
    if (empty($url)) {
        return 'URLが指定されていません。';
    }

    // 外部URLからデータを取得
    $response = wp_remote_get($url);

    // エラーチェック
    if (is_wp_error($response)) {
        return 'テキストの読み込みに失敗しました。';
    }

    // 取得したデータの処理
    $body = wp_remote_retrieve_body($response);
    return $body; // HTMLとしてそのまま返す
}

// ショートコードを作成
function display_dynamic_external_html($atts) {
    return fetch_dynamic_external_html_content($atts);
}
add_shortcode('dynamic_external_html', 'display_dynamic_external_html');

?&gt;</code></pre>



<p>上の２つのAppleScriptは、汎用性があります。</p>



<p>例えば、自宅サーバー用のWordPressのカスタムhtml記述については、URLはランダムな文字列を埋め込むことなく、素直なディレクトリの記述になっているので、（２）だけ使います。</p>



<p></p>



<h4 class="wp-block-heading">２　ChatGPTの活用</h4>



<p>上のAppleScriptですが、実は、ChatGPT（無料版の利用）の力を借りています。私は、「指示書を書いて、結果を検証して、間違いを指摘して訂正を求める」だけです。ChatGPTは、プログラミングは得意な分野だと思います。私は、特に活用法をどこかで学んだことはありませんが、質疑応答を、「解決して欲しい問題を書く、何を使って、どのような手順で（手順１　手順２　、、）、プログラミング記述して欲しいかを書く」という流れで繰り返すことができます。但し、即座に正しい解法になることはまずありません。出てきたエラーをそのまま伝えて、訂正を依頼する、それを、５〜６回繰り返して、辿り着く感じです。隘路に入ったためスタートに戻ることも、ままあります。</p>



<h4 class="wp-block-heading">３　マウスの左を３回クリック</h4>



<p>動画の中で登場する、マウスの左３回クリック、トリプルクリックは、このブログをご覧の方はご存知のことと思いますが、紹介します。</p>



<figure class="wp-block-video aligncenter">
<video controls
poster="https://www.dropbox.com/scl/fi/bxifz34udntupuho4jm9y/3-poster.png?rlkey=4dts2a2cmdjtxsynnxgksxdfr&#038;raw=1"
src="https://dl.dropboxusercontent.com/scl/fi/cw3iijw40y6thbop2310o/240117_-3.mp4?rlkey=g6mrd4yjfo81dyr9qioz49vai" 
playsinline="">
<track default="" 
src="https://dl.dropboxusercontent.com/scl/fi/xevdt3zrkbq0bcfueek2a/240118_-3-_.vtt?rlkey=emxpzxgr6cilqitdt8035rdif" 
label="日本語" srclang="ja" kind="subtitles">
</video>
<figcaption>＜マウスの左を３回クリック＞
</figcaption>
</figure>



<h4 class="wp-block-heading">４　2023年12月にDropboxリンクの構造が変更。個々のコンテンツ単位で制限管理ができる仕組みへ移行。</h4>



<p>DropboxリンクのURLですが、以前は&#8221;https://&#8230;&#8230;..？&#8221;まででした。2023年12月にrlkey=以降が追加になっています。トラッキング追跡のためか何らかの異常回避、情報収集のためでしょうか。ファイル単位でアクセス制限ができるようになるのかも知れません。いずれにしても、何らかの安全対策だと思います。　自宅サーバーは、サーバー単位か、そこまで細かく出来ていないので、Dropboxは一歩も二歩も進んでいます。</p>



<p><a rel="noopener" target="_blank" href="https://help.dropbox.com/ja-jp/share/force-download">Dropboxヘルプセンターにrlkeyを導入すること及び利用方法(レンダリングの強制 )の説明<span class="fa fa-external-link external-icon anchor-icon"></span></a>があります。この中で、ブラウザで直接画像を表示するには、つまりWordPressなどでリンク表示する場合は、<strong>raw=1を使ってリダイレクトをさせて使用する</strong>ように指示が書かれています。まだ移行が完了したとはしていないので、今後とも何らかの仕様の変更があるかも知れません。ウオッチする必要があります。</p>



<h4 class="wp-block-heading">５　Dropboxリンクを使うならファイル名は英数字で作るのが基本。</h4>



<p>Dropboxリンクは、ファイル名を変えても、フォルダを移動しても、変わりません。&#8221;<strong>https://ランダムな文字列/ファイル名?rlkey=ランダムな文字列</strong>&#8220;となっています。この<strong>ファイル名のところですが、日本語の部分が削除されます</strong>。ですから、ファイル名は、英数字だけでユニークな文字列をまず書いて、私は年月日プラス連番がいいと思いますが、そこに少しだけ短く日本語を加える書き方がよさそうです。</p>



<h4 class="wp-block-heading">６　ダウンロードを要求される問題。</h4>



<p>Dropboxリンクの末尾をraw=1に置き換えたURLを、WordPressの投稿中の文字列にリンクして再生しようとすると、ダウンロードを要求される場合があります。Dropboxはクラウドストレージが本業であって、データを受け渡すのが本業。だから、動画や画像も、ビジネス上のファイルのやり取りと同様に、利用者が一度自分のフォルダへダウンロードして、その後で、そのファイルを再生する。それが基本だろうと思います。しかしながら私のように、個人のWeb配信に使う場合は、ダウンロードを要求されるなら、それは不便過ぎて利用できないです。そこで、そのような個人的な小規模の発信者に対して、ランダム生成した非常に長いURLアドレスへリダイレクトするなら利用を可能にする、アクセスが集中するようなら視聴制限を加える、そうした条件の下で利用を許可しているということになります。</p>



<p>ともかく、間違いないのは、Dropbox動画ごとに、それを貼り付けた独立ページ（固定ページ）を自分で作ることです。そしてその独立ページをWordPressの文字列にリンク。そうすればWindows/Macほかでもダウンロードを要求されないでしょう。</p>



<h4 class="wp-block-heading">７　動的トグル</h4>



<p>小さな工夫の紹介ですが、上のスクリプトのところで、「字幕一覧のデータの投稿内引き込みを追加した&#8230;.」と記述しましたが、これの具体例が、以下のトグルです。</p>



<details translate="yes"><summary translate="yes">字幕一覧(クリック)</summary> <p translate="yes">
(00:00:00) Dropboxの動画をWordPressに貼り付ける<br>
(00:00:04) はい。それでは今からDropboxにある動画を、WordPress へ貼り付ける方法について紹介します。<br>
(00:00:17) まず結論からですが、Vimeoの代用にDropboxを使うことにします。　<br>
(00:00:26) 私の場合は元ネタの動画だとか写真はですね、 ほぼ全部Dropboxの中にありますので、<br>
(00:00:35) それを、簡単に加工して送信できればいいわけです。<br>
(00:00:43) 2つ目に、Dropboxですけれども、そのスピードはもちろん、その動画配信サービスの、 <br>
(00:00:50) YouTubeだとかVimeoには劣りますけども、<br>
(00:00:55) 自宅サーバーよりは速いです。<br>
(00:01:01) 3番目に、同じクラウドサービスに、Google ドライブがあります。<br>
(00:01:07) Googleドライブを使う方法を調べたが、<br>
(00:01:13) 字幕ファイルの同期の方法がよくわかりません。<br>
(00:01:17) GoogleとしてはYouTubeを利用すればいいと考えているのかなと感じます。　<br>
(00:01:26) そういった意味で、私にとってはですね、<br>
(00:01:30) このDropbox対Googleについては、<br>
(00:01:36) Dropboxが使いやすそうです。<br>
(00:01:41) それでは、使うための準備を進めます。<br>
(00:01:50) まず、Dropboxリンクは、そのままWordPressへ貼り付けても動かないです。 <br>
(00:01:59) 手直しする必要があります。<br>
(00:02:08) Dropboxリンクですけれども、<br>
(00:02:13) この以下のこの長いURLになってます。<br>
(00:02:19) 2023年ですね、12月からですね、この、rlkeyというものが加わってとても長くなりました。<br>
(00:02:29) この2行目からのこの部分ですね、<br>
(00:02:36) まあ、過剰な負荷だとか、安全対策が強化されたようです。<br>
(00:02:43) これに伴って、2023年12月以降は、WordPress用の貼り付けコードも変わってきています。<br>
(00:02:54) 残念ながらこのままでは、WordPressは再生できません。<br>
(00:03:01) この赤い部分ですね、dl=0の部分を、raw=1で置き換えます。<br>
(00:03:14) すなわち、以下のような形です。<br>
(00:03:22) これを作成します。<br>
(00:03:31) これをですね、マウスの操作だけで行うクイックアクションを作成します。AppleScriptを使います。<br>
(00:03:43) 以下のように作るのですが、<br>
(00:03:46) このスクリプトについては、ブログへ添付しますのでご覧ください。<br>
(00:03:52) このスクリプトについては、ブログへ添付しますのでご覧ください。<br>
(00:04:00) それで、作ったクイックアクションを実行して、置き換えが正しいかどうか確認します。<br>
(00:04:09) 動きをご覧ください。<br>
(00:04:16) 確認するテスト画像ですね、これです。<br>
(00:04:22) その上で右クリックをして、Dropboxリンクをコピーします。<br>
(00:04:31) それをメモにペーストします。 <br>
(00:04:36) ペースト、<br>
(00:04:38) でその上で、左クリックを3回、<br>
(00:04:44) で、右クリックをして、<br>
(00:04:48) サービスの中から、DropboxリンクをWordPress用に変換する、を選びます。<br>
(00:04:59) コピーされます。OK。<br>
(00:05:05) でそれを、<br>
(00:05:07) メモにペーストします。<br>
(00:05:10) こういった出来上がりになります。<br>
(00:05:14) 変えられた部分は、dl=0が、<br>
(00:05:23) raw=1に変わっています。<br>
(00:05:29) それではこの出来上がったものをクリックして確認してみましょう。<br>
(00:05:39) 確かに画像が出ます。<br>
(00:05:48) これだけでも、ですね、<br>
(00:05:53) このクイックアクション、汎用に使えるんですけれども、<br>
(00:05:57) もう一つAppleScriptのアプリケーションを組み合わせて、WordPressへの動画貼り付けコードを生成したいと思います。<br>
(00:06:12) 3番目、<br>
(00:06:14) WordPressへの動画貼り付けコードを生成します。<br>
(00:06:20) これはまた同じく、AppleScriptのスクリプトですけれども、スクリプトエディターで作ります。<br>
(00:06:29) 以下のような内容です。この内容もブログへ添付しますので、<br>
(00:06:40) コピーしてお使いください。<br>
(00:06:44) その結果のですね、<br>
(00:06:47) アプリケーションの実行の様子をご覧ください。<br>
(00:06:55) 最初にアプリケーションを起動させます。<br>
(00:07:11) それで、<br>
(00:07:15) 開始画面の画像URLを入れてください、ということで、最初にその画像ファイル、<br>
(00:07:26) を選び、その上で右クリックして、Dropboxリンクをコピーします。<br>
(00:07:33) それを、ダイアログボックスのところにペーストします。<br>
(00:07:40) その上で、左クリック3回、右クリック、サービスから、<br>
(00:07:48) 変換アクション、<br>
(00:07:53) コピーがされたらそれを、<br>
(00:07:57) ボックスに貼り付けます。<br>
(00:08:00) OK。<br>
(00:08:03) 次に、<br>
(00:08:06) 動画本体のURLを、<br>
(00:08:10) 変換します。<br>
(00:08:14) 目的の、<br>
(00:08:19) ファイルを選びます。<br>
(00:08:23) どれだ、<br>
(00:08:31) はい、右クリックして、Dropboxリンクのコピーして、<br>
(00:08:39) それを、ダイアログボックスにペーストして、<br>
(00:08:46) 左クリック3回、<br>
(00:08:51) 右クリック、<br>
(00:08:53) サービスの中からアクションを選び、変換したものを、<br>
(00:09:02) 置き換えます。<br>
(00:09:05) OK。<br>
(00:09:09) 次に、字幕ファイルのURLです。<br>
(00:09:14) 探します。<br>
(00:09:18) vttファイルです。 <br>
(00:09:23) 右クリックして、<br>
(00:09:26) リンクをコピーして、<br>
(00:09:29) ダイアログボックスにペーストします。左クリック3回、右クリック、<br>
(00:09:38) サービスの中からアクションを起動して、<br>
(00:09:42) 出来上がったコードを、<br>
(00:09:46) 貼り付けます。<br>
(00:09:48) OK。<br>
(00:09:51) 最後に動画の説明を記入します。<br>
(00:09:55) 何入れてもいいんですが、先頭の文字に小文字の不等号カッコ、これはダメです。<br>
(00:10:05) で、出来上がったものがこういった形でですね、コードが出来上がります。<br>
(00:10:23) OK。<br>
(00:10:25) クリップボードにコピーされますのでそれをWordPressへペーストします。<br>
(00:10:33) カスタムHTMLコードへ、<br>
(00:10:37) ペーストします。プレビューを押します。<br>
(00:10:47) 起動してみます。<br>
(00:10:55) ちゃんと動いてますね、<br>
(00:11:14) はい、正しくできています。<br>
(00:11:19) それでは以上で、Dropboxにある動画を、WordPressへ貼り付ける方法の説明を終わります。<br>
(00:11:29) ありがとうございました。<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>




<p>上の3つの動画の下部に挿入した字幕一覧のトグルと同じものです。このtxtファイルは、Dropboxの中にあります。上に掲載のfunction.phpをコピペしたあと、</p>



<pre class="wp-block-code"><code>&#091;dynamic_external_html url=""]</code></pre>



<p>上をカスタムhtmlに記述して、url=&#8221;&#8221;のところに当記事で説明した方法で変更したDropboxリンクを挿入します。Dropboxにあるこのtxtファイルを変更すると、全てのこの字幕一覧の表示が変更されます。当たり前といえばそうなのですが、なかなか便利です。動的トグルと呼んでおきます。</p>



<p></p>



<h4 class="wp-block-heading">８　直接リンクには3つのサーバーがあるが、不安定であり、モニタリング要。</h4>



<p>Dropboxから画像を直接リンクする方法は、正直、不安定です。以下に、同じ画像を、DropboxのURLをwww.dropbox.com（変更なし)の場合、dl.dropbox.comの場合、dl.dropboxusercontent.comの場合、を並べます。数日様子を見ていますが、www.dropbox.com(変更なし)がほぼ常に表示されています。これの特徴は、別のトークンURLに書き換えられて表示されるという２段階になっています。状況をウオッチしていきます。<br><span class="red"><s>2024.5.5時点で、www.dropbox.com raw=1は表示不可、dl.dropbox.com raw=1は表示可能となっています。</s></span><br></p>



<figure class="wp-block-image size-large is-resized"><a rel="noopener" target="_blank" href="https://dl.dropbox.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?rlkey=p2redrolq8klhrovdpk3c1wa5&amp;raw=1"><img decoding="async" src="https://dl.dropbox.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?rlkey=p2redrolq8klhrovdpk3c1wa5&amp;raw=1" alt="" style="width:840px;height:auto"/></a><figcaption class="wp-element-caption"><a rel="noopener" target="_blank" href="https://dl.dropbox.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?rlkey=p2redrolq8klhrovdpk3c1wa5&amp;raw=1">https://dl.dropbox.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?rlkey=p2redrolq8klhrovdpk3c1wa5&amp;raw=1<span class="fa fa-external-link external-icon anchor-icon"></span></a></figcaption></figure>



<figure class="wp-block-image size-large is-resized"><a rel="noopener" target="_blank" href="https://i0.wp.com/dl.dropboxusercontent.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?ssl=1"><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/dl.dropboxusercontent.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?w=1256&#038;ssl=1" alt="" style="width:840px;height:auto"/></a><figcaption class="wp-element-caption"><a rel="noopener" target="_blank" href="https://dl.dropboxusercontent.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?rlkey=p2redrolq8klhrovdpk3c1wa5&amp;raw=1">https://dl.dropboxusercontent.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?rlkey=p2redrolq8klhrovdpk3c1wa5&amp;raw=1<span class="fa fa-external-link external-icon anchor-icon"></span></a></figcaption></figure>



<figure class="wp-block-image size-large is-resized"><a rel="noopener" target="_blank" href="https://www.dropbox.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?rlkey=p2redrolq8klhrovdpk3c1wa5&amp;raw=1"><img decoding="async" src="https://www.dropbox.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?rlkey=p2redrolq8klhrovdpk3c1wa5&amp;raw=1" alt="" style="aspect-ratio:1;width:840px;height:auto"/></a><figcaption class="wp-element-caption"><a rel="noopener" target="_blank" href="https://www.dropbox.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?rlkey=p2redrolq8klhrovdpk3c1wa5&amp;raw=1">https://www.dropbox.com/scl/fi/vqp3klbp7ii4io0bzt8pq/240119_test.JPG?rlkey=p2redrolq8klhrovdpk3c1wa5&amp;raw=1<span class="fa fa-external-link external-icon anchor-icon"></span></a></figcaption></figure>
]]></content:encoded>
					
		
		<enclosure url="https://dl.dropboxusercontent.com/scl/fi/cw3iijw40y6thbop2310o/240117_-3.mp4?rlkey=g6mrd4yjfo81dyr9qioz49vai" length="0" type="video/mp4" />
<enclosure url="https://imakat.synology.me/wp-content/mmedia/2401221_Dropboxの動画をWordPressへ貼り付ける.mp4" length="476711955" type="video/mp4" />
<enclosure url="https://www.dropbox.com/scl/fi/oewlvtdcqeqp7d9w777t9/2401221_Dropbox-WordPress.mp4?rlkey=7mstp5fm6rgrtrgsvlun0vex5&#038;raw=1" length="0" type="video/mp4" />

		<post-id xmlns="com-wordpress:feed-additions:1">18942</post-id>	</item>
		<item>
		<title>【GAS】分散通知の仕組みを作る〜Googleアプリ、GAS及びAPIの活用　STEP5: ブログ(Blogger)への投稿・全体まとめ(5/5)</title>
		<link>https://imakat.com/2021/10/15/14054/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Fri, 15 Oct 2021 02:33:29 +0000</pubDate>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Blogger]]></category>
		<category><![CDATA[Googleスプレッドシート]]></category>
		<category><![CDATA[GAS]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=14054</guid>

					<description><![CDATA[＜分散通知の仕組みを作る　STEP5: ブログ(Blogger)への投稿＞別ページで表示 ブログは、時系列の掲示板であり、その中には、今回取り上げている緊急通知も含めていいと考えています。記事の性格は、楽しい思い出づくり [&#8230;]]]></description>
										<content:encoded><![CDATA[
<hr class="wp-block-separator has-text-color has-key-color-color has-css-opacity has-key-color-background-color has-background is-style-wide"/>



<p>＜分散通知の仕組みを作る　STEP5: ブログ(Blogger)への投稿＞<br><span class="fz-12px"><a href="https://imakat.com/page-11646-4-2-3-2/" target="_blank">別ページで表示</a></span></p>



<img decoding="async" src="https://docs.google.com/drawings/d/e/2PACX-1vS9vKizc6xV7tI7qoc0Xd0k1DHE11asFoRTPnnevUBwBrBuY4Eiy6GDSQ694HDKRS9TTmpMy_YBzZ1W/pub?w=1440&amp;h=1080">



<hr class="wp-block-separator has-text-color has-key-color-color has-css-opacity has-key-color-background-color has-background is-style-wide"/>



<p>ブログは、時系列の掲示板であり、その中には、今回取り上げている緊急通知も含めていいと考えています。記事の性格は、楽しい思い出づくりとは異なりますが、緊急かつ重要な情報は、どこにでも飛び込んでいいものと考えます。</p>



<p>今回、無料のブログの選択には、多少悩みました。この種のサービスは打ち切りになることが多いからです。その中から、Googleと相性がいいもの、シンプルなもの、であるBloggerを選択しました。Bloggerは他のサービスへの移動、例えばWordPressへの移動などについても、説明が数多くあることも安心です。</p>



<p></p>



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



<h4 class="wp-block-heading">＜1＞ GoogleSSへの取り込み</h4>



<p>流れとしては、通知文GoogleSS→Blogger送信用GoogleSS→Blogger、です。APIは使いません。Bloggerにはメール投稿機能が備わっており、それを利用します。</p>



<p>Blogger送信用GoogleSSの画面は以下です。</p>



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



<p>この画面には、Googleフォームへ入力した通知文GoogleSSが取り込まれるため、内容を確認するだけです。問題がなければ、「Blogger投稿」ボタンを押します。</p>



<p><strong>通知文の読み込み：</strong></p>



<p>IMPORTRANGE関数を使います。<br>読み込みたいGoogleSSのURLが、下記のようになっていたとして、</p>



<pre class="wp-block-code"><code>https:&#47;&#47;docs.google.com/spreadsheets/d/【この部分】/edit#gid=0</code></pre>



<p>【この部分】を以下の場所に当てはめてください。sheet1は実際のシート名、A10,A12のところも実際のセル位置を当てはめてください。</p>



<p>Bloggerでは、タイトル、本文と関係リンク、の２データを、通知文GoogleSS から読み込んで、このBlogger用GoogleSSへ取り込みます。</p>



<pre class="wp-block-code"><code>=IMPORTRANGE("【この部分】","sheet1!A10")
=IMPORTRANGE("【この部分】","sheet1!A12")</code></pre>



<h4 class="wp-block-heading">＜2＞GAS記述</h4>



<p><strong>GASの記述：</strong></p>



<p>このままコピペください。<span class="bold-red">赤字</span>は、例示です。</p>



<p>STEP2の電子メールと、考え方は同じです。</p>



<p>・<span class="bold-red">nihonnofujisan001</span>は、google個人アカウントです。<br>・投稿用のメールアドレスが、Bloggerから与えられます。その時【任意の文字列】を設定します。<br></p>



<pre class="wp-block-code"><code>function sendMail(){
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  const from = '<span class="bold-red">nihonnofujisan001</span>@gmail.com';
  const to = '<span class="bold-red">nihonnofujisan001</span>.【任意の文字列】@blogger.com';
  const subject = sheet.getRange(<span class="bold-red">3,1</span>).getValue();
  const body = sheet.getRange(<span class="bold-red">5,2</span>).getValue();
GmailApp.sendEmail(to, subject, body);
}
</code></pre>



<h4 class="wp-block-heading"><strong>＜３＞なぜ30分以内？：</strong></h4>



<p>ブログ（ネット掲示板）をユーザーが見るのを30分以内、としているのは、ブログには、Push7からRSS連携：</p>



<p><strong><span class="bold-red">赤字</span></strong>は、例示です。</p>



<pre class="wp-block-code"><code>https://<span class="bold-red">nihonnofujisan001</span>.blogspot.com/feeds/posts/default</code></pre>



<p>を貼り付けています。こうしたRSSフィードは、様々なサービスがあるので、もっと短い巡回時間のものもあると思います。一応、Push7の巡回は30分以内となっています。30分以内は標準的かと思います。</p>



<p>ちなみに私は、Push7を、ブログ更新とは切り離した緊急通知用と、ブログ更新とリンクした一般通知用の２箇所に貼り付けています。</p>



<h4 class="wp-block-heading">＜４＞全体のまとめ</h4>



<h5 class="wp-block-heading">１）配信数の制約に注意。緊急通知だけなら、会員700人以下なら無料で運用できそう。</h5>



<p></p>



<p></p>



<figure class="wp-block-table"><table><tbody><tr><td>サービス名</td><td class="has-text-align-center" data-align="center">無料：同時に1回何通まで</td><td class="has-text-align-center" data-align="center">無料：日・月の合計数の上限</td><td class="has-text-align-center" data-align="center">想定最大通知数</td><td class="has-text-align-center" data-align="center">想定利用者上限(歩留り70%)</td></tr><tr><td><a rel="noopener" target="_blank" href="https://support.google.com/mail/answer/22839?hl=ja#zippy=%2C送信できるメールの制限数に達しました">Googleグループメール<span class="fa fa-external-link external-icon anchor-icon"></span></a> </td><td class="has-text-align-center" data-align="center">500通</td><td class="has-text-align-center" data-align="center">500通/日</td><td class="has-text-align-center" data-align="center">週2回</td><td class="has-text-align-center" data-align="center">175人</td></tr><tr><td><a rel="noopener" target="_blank" href="https://line-sm.com/blog/lineofficial_message_count/">LINE公式アカウント<span class="fa fa-external-link external-icon anchor-icon"></span></a></td><td class="has-text-align-center" data-align="center"></td><td class="has-text-align-center" data-align="center">1000通/月</td><td class="has-text-align-center" data-align="center">週2回</td><td class="has-text-align-center" data-align="center">88人</td></tr><tr><td><a rel="noopener" target="_blank" href="https://push7.jp/blog/faq/">Push7<span class="fa fa-external-link external-icon anchor-icon"></span></a></td><td class="has-text-align-center" data-align="center"></td><td class="has-text-align-center" data-align="center">5000通/月</td><td class="has-text-align-center" data-align="center">週2回</td><td class="has-text-align-center" data-align="center">437人</td></tr><tr><td></td><td class="has-text-align-center" data-align="center"></td><td class="has-text-align-center" data-align="center"></td><td class="has-text-align-center" data-align="center">合計</td><td class="has-text-align-center" data-align="center">700人</td></tr></tbody></table></figure>



<p>現在、私は、全世帯が、3つから１つだけ選んで登録するとして、600〜700世帯を想定しています。トータルとしては、この３つのサービスで、お金をかけずに続けそうですが、自由に選んでもらうとLINEに集中するのでは。LINEの無料のワクは非常に小さいです。後でPush7やメールへ変更を促すことになるのでしょうかね。いずれにしても、緊急通知は一方通行、仮に事態が集中したとしても週２〜３回に収まるのではないでしょうか。</p>



<p>緊急通知の配信基準を設けておく必要があるでしょう。</p>



<p>例として、</p>



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



<p>・水害・土砂災害における避難警戒レベル３以上の発令に伴い、自治体から、当該地域あてに発出された情報。</p>



<p>・地域の災害対策組織の長（自治会長や町内会長など）が決定した配信情報。例えば、道路の陥没、建物の倒壊、断層など上部自治体の危険箇所情報からこぼれ落ちた地域住民向けの情報。</p>



<p>・事件事故の発生に伴い、警察消防から発出された、地域住民への警戒情報。</p>



<p>・その他、自治体から要請があり当該長が了承した緊急通知。例えば、同報無線の能力不足、故障時の支援も含む。</p>



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



<p>など。何がどう重なるか分かりませんが、不幸が重なったとしても週２〜３回で収まると、私は想像します。</p>



<p></p>



<p>しかし世帯数が1,000世帯を超えるようだと、レンタルサーバーを使うなど、有料にならざるを得ないのでは。</p>



<p>理想的には、500〜600世帯ごとに、このような仕組みが運営できれば、機動的でしょう。</p>



<h5 class="wp-block-heading">２）異なったサービスだが、操作方法は統一する。その上で、一つ一つ、送信成功を確かめながら送るのがいい。</h5>



<p>今回の、分散通知ですが、使用頻度が非常に低いです。防災などの緊急通知が主目的。そんな災害は頻繁にはないです。ですから、わかりやすく言えば、<strong>この仕組みの使い方を忘れた頃、突然、使うことになる</strong>のだと想像します。従って、覚える操作方法は一つだけにすること。そしてそれを、それぞれのサービスに適用して、送信出来るようにしておくのが重要だと考えます。</p>



<p></p>



<h5 class="wp-block-heading">3)  GoogleSSをアプリ毎に別ファイルにした理由</h5>



<p>アプリ側はそれぞれ異なる会社のサーバーになります。全体が一箇所のトラブルに巻き込まれないように、GoogleSSは、シート別ではなく、ファイル別に用意しました。</p>



<h5 class="wp-block-heading">4）目標：緊急通知を、スマホから、１３分以内で、７００人へ送る仕組みを、タダで作る。</h5>



<p>今回、この目標を達成できたような気もしていますが、実用上、どうなるかはわかりません。</p>



<p>今回、私のブログを読んで下さった方は、私同様、開発費もタダにすることができると思います。これからも工夫改善は続きます。</p>



<p><a href="https://imakat.com/2021/10/13/13863/" target="_blank">STEP1へ戻る</a></p>



<p>以上</p>


]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">14054</post-id>	</item>
		<item>
		<title>【GAS】分散通知の仕組みを作る〜Googleアプリ、GAS及びAPIの活用　STEP4: Push7のプッシュ通知(4/5)</title>
		<link>https://imakat.com/2021/10/15/14021/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Thu, 14 Oct 2021 22:33:17 +0000</pubDate>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[Googleスプレッドシート]]></category>
		<category><![CDATA[GAS]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Push7]]></category>
		<category><![CDATA[プッシュ通知]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=14021</guid>

					<description><![CDATA[＜分散通知の仕組みを作る　STEP4: Push7のプッシュ通知＞別ページで表示 LINEや電子メールは双方向の会話の機能があるので、「りんごちゃん」などニックネームで構わないが何らかのID情報が配信側に伝わります。しか [&#8230;]]]></description>
										<content:encoded><![CDATA[
<hr class="wp-block-separator has-text-color has-key-color-color has-css-opacity has-key-color-background-color has-background is-style-wide"/>



<p>＜分散通知の仕組みを作る　STEP4: Push7のプッシュ通知＞<br><span class="fz-12px"><a href="https://imakat.com/page-11646-4-2-3/" target="_blank">別ページで表示</a></span></p>



<img decoding="async" src="https://docs.google.com/drawings/d/e/2PACX-1vQbOAqUsZ3ihHYbzYqnutFIBTTZN5oywF3wjFlkdzol2WoBJJEUkPHV0fhSYG_Szb22ufvPz2YRWk85/pub?w=1440&amp;h=1080">



<hr class="wp-block-separator has-text-color has-key-color-color has-css-opacity has-key-color-background-color has-background is-style-wide"/>



<p>LINEや電子メールは双方向の会話の機能があるので、「りんごちゃん」などニックネームで構わないが何らかのID情報が配信側に伝わります。しかし、利用者側には、それすら知られたくない人もいます。</p>



<p>Push7は、ニックネームすら入力不要、です。敷居が低いです。</p>



<p>Push7に似た仕組みは、既にネット上に溢れています。ふだんサイトを見ていると、ヒョコッと顔を出して、「登録しませんか」と誘いかけられ、即座に、×、拒否、NO、不要を返事する、それが条件反射になっているあれです（ブラウザの設定でポップアップを禁止に出来ると思いますが）。</p>



<p>今私は、緊急通知を準備しているので、ポップアップ禁止設定にしたおかげで目にも触れない、というのでは困ります。そこで、サイトの文面の中で、説明を加えて、ボタンを押してもらって申し込んでもらう手順にしています。このPush7のサイトへの設置方法の説明は、長くなるので、この記事では、割愛します。</p>



<p></p>



<p>このSTEP4における配信作業の流れでは、Push7のアプリは何も触りません。</p>



<p>Push7のアプリをスマホから触りたくない理由ですが、プッシュ通知を打ち込むまでの画面の操作が非常に扱いにくい点があります。アプ通知文がSTEP1で作成済みならば、STEP2、STEP3とやることはほぼ同じです。ChromeからGoogleSSを立ち上げる-&gt;PC版サイトを選ぶ-&gt;iphoneを横向きにする-&gt;閉じるをクリック-&gt;内容を一応点検したら「Push7投稿」ボタンをクリック。という手順。</p>



<p>Push7のいい点は、管理する側における、利用者の登録や削除については、作業は何もないです。</p>



<p>実に簡単です。</p>



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



<h4 class="wp-block-heading">＜1＞ GoogleSSへの取り込み</h4>



<p>Push7で送信する内容のうち、毎回変更されるのは、タイトル、関係リンク、本文の３個です。</p>



<p></p>



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



<p>この画面には、Googleフォームへ入力した通知文が取り込まれるため、内容を確認するだけです。問題がなければ、「Push7投稿」ボタンを押します。</p>



<p><strong>通知文の読み込み：</strong></p>



<p>IMPORTRANGE関数を使います。<br>読み込みたいGoogleSSのURLが、下記のようになっていたとして、</p>



<pre class="wp-block-code"><code>https:&#47;&#47;docs.google.com/spreadsheets/d/【この部分】/edit#gid=0</code></pre>



<p>【この部分】を以下の場所に当てはめてください。sheet1は実際のシート名、A10,A12,A14のところも実際のセル位置を当てはめてください。</p>



<p>Push7では、タイトル、関係リンク、本文の３データを、通知文GoogleSS から読み込んで、このPush7用GoogleSSへ取り込みます。</p>



<pre class="wp-block-code"><code>=IMPORTRANGE("【この部分】","sheet1!A10")
=IMPORTRANGE("【この部分】","sheet1!A12")
=IMPORTRANGE("【この部分】","sheet1!A14")</code></pre>



<h4 class="wp-block-heading">＜2＞APIの取得とGAS記述</h4>



<p><strong>APIの取得：</strong></p>



<p><a rel="noopener" target="_blank" href="https://push7.jp">Push7<span class="fa fa-external-link external-icon anchor-icon"></span></a>は、親切に、API設置方法などが解説されています。</p>



<p><a rel="noopener" target="_blank" href="https://push7.jp/docs/development/api/">Push7 APIの利用<span class="fa fa-external-link external-icon anchor-icon"></span></a>　←この中の「Webプッシュ通知を送信するAPI」の項目が参考になります。</p>



<p>Push7は、メールアドレスとパスワードで登録できます。次に、プロジェクトを例えば「ABC会_通知」などとつけて設置すると、そのプロジェクトごとに、下記のように、App NumberとAPI Keyが発行されます。</p>



<figure class="wp-block-image size-large"><a href="https://imakat.com/rd.php?id=ACBb1sf3.png" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=ACBb1sf3.png" alt=""/></a><figcaption class="wp-element-caption">Push7 API : API NumberとAPI Keyを取得する。</figcaption></figure>



<p></p>



<p></p>



<p><strong>GASの記述：</strong></p>



<p>このままコピペください。<span class="bold-red">赤字</span>は、例示です。</p>



<p>・iconは、ここに指定した画像が選択されて通知に表示されます。<br>・urlは、表示された通知画面をクリックすると移動するサイトです。<br>・disappear_instantlyは、falseにすると画面の表示にタッチされるまでは表示が残ります。trueにすると数秒後には消えます。</p>



<pre class="wp-block-code"><code>const notifyPush7 = () =&gt; {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  const apikey = "【上画像のAPI Key】"
  const appno = '【上画像のApp Number】'
  const url = 'https://api.push7.jp/api/v1/【上画像のApp Number】/send';
  const headers = {
    'Content-Type' : 'application/json; charset=UTF-8',
    'Authorization' : 'Bearer ' + apikey,
 };
const data = {
'title': sheet.getRange(<span class="bold-red">3,1</span>).getValue(),
'body' : sheet.getRange(<span class="bold-red">7,1</span>).getValue(),
'icon' : "<span class="bold-red">https://***.com/****.jpeg</span>",
'url' :  sheet.getRange(<span class="bold-red">5,1</span>).getValue(),
'apikey' : "【上画像のAPI Key】",
'disappear_instantly' : false,
//'transmission_time": "2021/10/10 10:10"
//'query' : true,
}
const options = {
  'method' : 'post',
  'headers': headers,
  'payload': JSON.stringify(data)
};
UrlFetchApp.fetch(url,options);
}
</code></pre>



<p>具体的には、以下の、アプリによる送信画面を見て、対応関係を確認ください。</p>



<p>この「タイトル」「URL」「内容」の部分を、STEP1で作った通知文GoogleSSから、自動的に取り込むプログラムになっています。</p>



<p></p>



<figure class="wp-block-image size-large"><a href="https://imakat.com/rd.php?id=4yzyetYc.png" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=4yzyetYc.png" alt=""/></a><figcaption class="wp-element-caption">Push7アプリの新規プッシュ通知の画面</figcaption></figure>



<p>次回のSTEP5は、Googleが提供するブログであるBloggerへ、同じ通知文を投稿する方法を説明します。割と簡単です。</p>



<p><a href="https://imakat.com/2021/10/15/14054/" target="_blank">STEP5</a></p>



<p>以上</p>


]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">14021</post-id>	</item>
	</channel>
</rss>
