<?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>AppleScript | imakat.com</title>
	<atom:link href="https://imakat.com/tag/applescript/feed/" rel="self" type="application/rss+xml" />
	<link>https://imakat.com</link>
	<description>工夫と改善で人生をちょっと豊かに</description>
	<lastBuildDate>Tue, 10 Mar 2026 06:41:30 +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>AppleScript | 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>【Gemini/ChatGPT】スクリプトや記事を日本語要約＋保存するMac用スクリプト</title>
		<link>https://imakat.com/2025/10/12/27668/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Sat, 11 Oct 2025 23:34:29 +0000</pubDate>
				<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[Automator]]></category>
		<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[クイックアクション]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=27668</guid>

					<description><![CDATA[26.1.15追記：【Gemini】Gemini版を追加。文字列をコピーした後、マウスの右クリックで→サービス、から起動する形です。無料でも使えます。 【ChatGPT】～無料版でも動く、ローカル完結の超シンプル連携法～ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>26.1.15追記：<br><strong>【<span class="fz-14px"><span class="fz-16px"><span class="fz-18px">Gemini】</span></span></span></strong>Gemini版を追加。文字列をコピーした後、マウスの右クリックで→サービス、から起動する形です。無料でも使えます。<br></p>



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



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1lML0yZwWbv-y8o1QPXb3zBTGEBuSimvBTgOTFrW_RjY/edit?usp=sharing">Gemini APIキー取得方法と活用<span class="fa fa-external-link external-icon anchor-icon"></span></a></td></tr><tr><td>要約：このAppleScriptスクリプトは、ユーザーが選択したテキストをGoogle Gemini APIで要約し、その結果と元の本文をファイルに保存する自動化ツールです。右クリックで選択されたテキストを受け取り、処理前に内容をプレビューして続行を確認します。スクリプトはPython3とcurlコマンドを使い、Gemini APIにアクセス。<code>MY_API_KEY</code>を用いて、利用可能なモデルから<code>generateContent</code>をサポートするモデルを自動選択し、指定された文字数（MAX_SUMMARY_CHARS）で日本語の要約をリクエストします。Geminiからの出力は、要約文とその後に続く元の本文で構成されます。処理が完了すると、<code>SAVE_DIR</code>にタイムスタンプと要約の最初の行から生成されたタイトル（TITLE_MAX_CHARSで制限、ファイル名として安全化）を含むUTF-8形式のテキストファイルとして保存されます。処理状況やエラーは通知でユーザーに伝えられます。<br>Automator<br>ワークフローが受け取る項目：テキスト<br>選択肢：すべてのアプリケーション</td></tr><tr><td><a href="https://imakat.com/script_list/?pubtxt=geminiを使った日本語要約_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>



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



<p><strong>【<span class="fz-14px"><span class="fz-16px"><span class="fz-18px">ChatGPT】</span></span></span></strong><br><strong>～無料版でも動く、ローカル完結の超シンプル連携法～</strong><br>ChatGPTでテキストを要約したいとき、毎回アプリを開いてコピペするのは意外と手間です。そこで、AppleScriptとChatGPTデスクトップアプリを連携させて、「クリップボードの内容を自動でChatGPTに貼り付け→要約→テキストファイルに保存」までを数クリックで完結させる仕組みを紹介します。ChatGPTの無料版でも動作し、APIキーや外部サービスは不要です。</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=62_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=2MuRdRkf.png" playsinline preload="metadata" style="width:100%;height:auto;">  <source src="https://imakat.com/rd.php?id=ZJjPNzrn.mp4" type="video/mp4">  <track src="https://imakat.com/rd.php?id=dnzQfkpR.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>)  ChatGPTによる日本語要約とTXTファイル保存のかんたん化<br>
(<a href="#" class="imk-cue" data-seek="0:20" translate="no">00:00:20</a>)   今回は、ChatGPTの活用ということで、わかりやすい使い方を紹介します。<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:47" translate="no">00:00:47</a>)  それが簡単にできれば結構便利です。<br>
(<a href="#" class="imk-cue" data-seek="0:52" translate="no">00:00:52</a>)  ちょっとやってみましょうか。<br>
(<a href="#" class="imk-cue" data-seek="0:55" translate="no">00:00:55</a>)  今、ChatGPTでPythonのスクリプトを書いてもらったとします。<br>
(<a href="#" class="imk-cue" data-seek="1:05" translate="no">00:01:05</a>)  こういうものですね。<br>
(<a href="#" class="imk-cue" data-seek="1:09" translate="no">00:01:09</a>)  このPythonのスクリプトが、迷子になった場合、その中身が全く分からなくなってしまうので、<br>
(<a href="#" class="imk-cue" data-seek="1:19" translate="no">00:01:19</a>)  要約した内容を付けて、日時を付けて、タイムスタンプを付けて、そして本文を添えて<br>
(<a href="#" class="imk-cue" data-seek="1:29" translate="no">00:01:29</a>)  保存するという形にしたいと思います。<br>
(<a href="#" class="imk-cue" data-seek="1:36" translate="no">00:01:36</a>)  今ここに、Pythonスクリプトが出来上がっていたとします。<br>
(<a href="#" class="imk-cue" data-seek="1:42" translate="no">00:01:42</a>)  ここで、「コピーをする」を押します。<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:49" translate="no">00:01:49</a>)  次に、作っておいた、CHATGPT用の要約、TXT保存のアプリですね、<br>
(<a href="#" class="imk-cue" data-seek="2:02" translate="no">00:02:02</a>)  これをSTREAM DECKから起動します。<br>
(<a href="#" class="imk-cue" data-seek="2:09" translate="no">00:02:09</a>)  そうすると、この内容を保存しますか？ということで、　<br>
(<a href="#" class="imk-cue" data-seek="2:15" translate="no">00:02:15</a>)  スクリプトの先頭の120字をこのように紹介してくれます。 　　<br>
(<a href="#" class="imk-cue" data-seek="2:21" translate="no">00:02:21</a>)  間違いがないかの確認です。<br>
(<a href="#" class="imk-cue" data-seek="2:25" translate="no">00:02:25</a>)  続行を押します。<br>
(<a href="#" class="imk-cue" data-seek="2:29" translate="no">00:02:29</a>)  次に、ChatGPTによる要約を挿入しますか？と聞かれます。<br>
(<a href="#" class="imk-cue" data-seek="2:35" translate="no">00:02:35</a>)  はい、を選びます。<br>
(<a href="#" class="imk-cue" data-seek="2:38" translate="no">00:02:38</a>)  そうするとChatGPTが走ります。<br>
(<a href="#" class="imk-cue" data-seek="2:43" translate="no">00:02:43</a>)  非常に短い時間で、今のスクリプトの内容を日本語で300文字以内で、説明してくれます。<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:04" translate="no">00:03:04</a>)  次にこれを、ChatGPTによって要約された文章をコピーします。　<br>
(<a href="#" class="imk-cue" data-seek="3:13" translate="no">00:03:13</a>)  次に、取得を押します。　<br>
(<a href="#" class="imk-cue" data-seek="3:23" translate="no">00:03:23</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:51" translate="no">00:03:51</a>)  という形の保存用のファイルが出来上がります。<br>
(<a href="#" class="imk-cue" data-seek="3:59" translate="no">00:03:59</a>)  次の活用例を紹介します。<br>
(<a href="#" class="imk-cue" data-seek="4:05" translate="no">00:04:05</a>)  今ご覧のように、英文があります。　<br>
(<a href="#" class="imk-cue" data-seek="4:11" translate="no">00:04:11</a>)  この英文を日本語に翻訳して、日本語で300字以内に要約したものを作ります。　<br>
(<a href="#" class="imk-cue" data-seek="4:22" translate="no">00:04:22</a>)  そして、日時と要約とこの本文ですね。これを３点セットにして一つのファイルを作ります。<br>
(<a href="#" class="imk-cue" data-seek="4:34" translate="no">00:04:34</a>)  やってみます。<br>
(<a href="#" class="imk-cue" data-seek="4:39" translate="no">00:04:39</a>)  このようにして選択します。コピーを押します。次に、　STREAM DECKのアプリを起動します。<br>
(<a href="#" class="imk-cue" data-seek="4:45" translate="no">00:04:45</a>)  コピーを押します。<br>
(<a href="#" class="imk-cue" data-seek="4:49" translate="no">00:04:49</a>)  次に、SREAM DECKのアプリを起動します。<br>
(<a href="#" class="imk-cue" data-seek="4:58" translate="no">00:04:58</a>)  この内容を保存しますか？ということで文章の先頭の120字の紹介があります。　<br>
(<a href="#" class="imk-cue" data-seek="5:06" translate="no">00:05:06</a>)  これで間違いなしということで続行します。<br>
(<a href="#" class="imk-cue" data-seek="5:10" translate="no">00:05:10</a>)  ChatGPTによる要約を挿入しますか？はい。<br>
(<a href="#" class="imk-cue" data-seek="5:20" translate="no">00:05:20</a>)  この場合、時々、すぐに起動せずに下のボックスに英文が入ってしまうことがありますので、　　　<br>
(<a href="#" class="imk-cue" data-seek="5:28" translate="no">00:05:28</a>)  その場合は、焦らずに、右側のこのボタンを押します。<br>
(<a href="#" class="imk-cue" data-seek="5:40" translate="no">00:05:40</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:57" translate="no">00:05:57</a>)  これをコピーします。<br>
(<a href="#" class="imk-cue" data-seek="6:08" translate="no">00:06:08</a>)  そして、取得を押します。<br>
(<a href="#" class="imk-cue" data-seek="6:17" translate="no">00:06:17</a>)  そうしますと先頭に、一つ出来上がっています。　<br>
(<a href="#" class="imk-cue" data-seek="6:27" translate="no">00:06:27</a>)  内容を確認します。<br>
(<a href="#" class="imk-cue" data-seek="6:32" translate="no">00:06:32</a>)  日時、次に要約した文章、その下に英文の本文が入っています。　<br>
(<a href="#" class="imk-cue" data-seek="6:45" translate="no">00:06:45</a>)  これでいいですね。<br>
(<a href="#" class="imk-cue" data-seek="6:54" translate="no">00:06:54</a>)  最後に、３つ目の例を紹介します。<br>
(<a href="#" class="imk-cue" data-seek="6:59" translate="no">00:06:59</a>)  URLですね。<br>
(<a href="#" class="imk-cue" data-seek="7:04" translate="no">00:07:04</a>)  ご覧のように、一つURLがあったとします。<br>
(<a href="#" class="imk-cue" data-seek="7:09" translate="no">00:07:09</a>)  このURLの中身を、300文字以内の日本語で要約して、日時、要約、本文と、いや本文といっても、このURLだけですが。<br>
(<a href="#" class="imk-cue" data-seek="7:27" translate="no">00:07:27</a>)  それを一つのファイルにします。<br>
(<a href="#" class="imk-cue" data-seek="7:31" translate="no">00:07:31</a>)  やってみます。<br>
(<a href="#" class="imk-cue" data-seek="7:38" translate="no">00:07:38</a>)  コピー<br>
(<a href="#" class="imk-cue" data-seek="7:46" translate="no">00:07:46</a>)  ChatGPT用要約TXT保存のアプリを起動します。<br>
(<a href="#" class="imk-cue" data-seek="7:52" translate="no">00:07:52</a>)  この内容を保存しますか？続行。<br>
(<a href="#" class="imk-cue" data-seek="7:58" translate="no">00:07:58</a>)  ChatGPTによる要約を挿入しますか？はい。<br>
(<a href="#" class="imk-cue" data-seek="8:18" translate="no">00:08:18</a>)  要約が済みました。<br>
(<a href="#" class="imk-cue" data-seek="8:23" translate="no">00:08:23</a>)  どうもスマホを公共の充電器に接続すると、データを盗まれる危険があるので注意してください、という文章ですね。<br>
(<a href="#" class="imk-cue" data-seek="8:43" translate="no">00:08:43</a>)  この文章をコピーします。　<br>
(<a href="#" class="imk-cue" data-seek="8:51" translate="no">00:08:51</a>)  そして取得を押します。<br>
(<a href="#" class="imk-cue" data-seek="8:56" translate="no">00:08:56</a>)  そうすると、一番上に今の内容が入ってきました。<br>
(<a href="#" class="imk-cue" data-seek="9:05" translate="no">00:09:05</a>)  ご覧のように、一番上に、日時、要約、内容、まあ時々文章が変になっている場合もあるのですかね。　　　<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:24" translate="no">00:09:24</a>)  その辺は、愛嬌ですね。<br>
(<a href="#" class="imk-cue" data-seek="9:29" translate="no">00:09:29</a>)  それからURLと、いう形になります。<br>
(<a href="#" class="imk-cue" data-seek="9:37" translate="no">00:09:37</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>



<ol class="wp-block-list">
<li style="font-style:normal;font-weight:700">クリップボードのテキストを取得</li>



<li style="font-style:normal;font-weight:700">ChatGPTアプリを自動起動</li>



<li style="font-style:normal;font-weight:700">要約プロンプトを自動入力（例：「以下のテキストを日本語で400字以内に要約してください」）</li>



<li style="font-style:normal;font-weight:700">ChatGPTが要約を生成</li>



<li style="font-style:normal;font-weight:700">ユーザーが要約をコピー</li>



<li style="font-style:normal;font-weight:700">指定フォルダにテキストファイルとして自動保存</li>
</ol>



<p>１のクリップボードのテキスト取得がミソになっています。マウス右クリックでコピーしたものです。保存ファイル名は「YYYYMMDD-HHMMSS_タイトル.txt」という形式で、<br>例：/Volumes/NO3_SSD/Dropbox/dropbox_1/ChatGPTによる要約と本文/ に保存されます。</p>



<h4 class="wp-block-heading">■ 実装の手順</h4>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="width:10%">(1)</td><td>下の青色のボタンから、スクリプト(txtファイル)をダウンロードします。</td></tr><tr><td style="width:10%">(2)</td><td>スクリプトエディタで、例えば&#8221;Save_Clipboard_with_Summary&#8221;と名前つけて、スクリプトファイル&#8221;Save_Clipboard_with_Summary.scpt&#8221;として保存します。</td></tr><tr><td style="width:10%">(3)</td><td>(a)Stream Deckからは&#8221;Save_Clipboard_with_Summary.scpt&#8221;が直接呼べます。<br>(b)クイックアクションからの起動は、Automator→クイックアクション→ワークフローが受け取る現在の項目：テキスト、使用できるアプリケーション：任意のアプリケーション→「AppleScriptを実行」のボックスを置く→(4)<br></td></tr><tr><td>(4)</td><td><strong>run script (POSIX file &#8220;/&lt;あなたのファイルパス&gt;/Save_Clipboard_with_Summary.scpt&#8221;)</strong></td></tr><tr><td>(5)</td><td>アプリ名を例えば&#8221;ChatGPT要約付きTXT保存&#8221;として保存します。</td></tr><tr><td colspan="2"><a href="https://imakat.com/?pubtxt=ChatGPT連携_要約保存Mac用スクリプト_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 colspan="2">Windowsへ実装したい場合は、ChatGPTに上のtxtファイルを添付して、「同じ働きをWindowsで実装するスクリプト作成と実装手順を指示ください」としてください。</td></tr></tbody></table></figure>



<h4 class="wp-block-heading">■ 操作方法</h4>



<p>使い方はとても簡単です。<br>要約したいテキストをコピーし、このアプリを実行するだけ。<br>ChatGPTが起動して自動で要約を生成し、その結果をコピーすればファイルが自動保存されます。<br>これで「ChatGPTで要約→保存」までが一瞬で完了します。</p>



<p>さらに、右クリック（コンテキストメニュー）から呼び出せる「クイックアクション」として登録しておくと、<br>ブラウザやメモアプリ上でテキストを選択 → コピー → 右クリックで「要約して保存」を実行、<br>という直感的な操作が可能になります。<br>Mac標準のAutomatorで簡単に登録できるため、日常の作業フローに自然に組み込めます。</p>



<h4 class="wp-block-heading">■ ChatGPTの文字列のコピーが扱えない！裏ワザあります。</h4>



<p>ブラウザ、テキストエディット、メモなどにある文章は、コピーを行なった後、このアプリをMacのキーボードショートカットに登録して、要約保存は、下記のアクセス許可を経て使用できるようになります。私は、「ChatGPT要約付きTXT保存」アプリに⌥(Option)+ファンクション(F)1を登録しました。</p>



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



<p><br>しかし、本家本元のChatGPTに表示される文字や文章は、コピーした後、アプリが起動しないという問題が生じます。その場合の裏ワザです。</p>



<p>それは、文字列のコピーは、Web版ChatGPTから行い、アプリを起動してインストール版ChatGPTで要約させ、最後に保存する流れで連携する方法です。以下のような挙動になります。</p>



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



<p><br><br></p>



<h4 class="wp-block-heading">■ 注意：アクセス許可が必要な場合があります</h4>



<p>クイックアクションを使って、Safari・Chrome・PDFビューアなど<br>さまざまなアプリからテキストをコピーして要約に取り込む場合、<br>まれに「エラーが出る」「テキストが取得できない」ことがあります。</p>



<p>これは、そのアプリのテキスト内容へのアクセスが macOS で制限されているためです。<br>その場合は以下の手順でアクセスを許可すると解決します。</p>



<p><strong>対処方法：<br>1. 「システム設定」→「プライバシーとセキュリティ」を開く<br>2. 左側のメニューから「アクセシビリティ」または「フルディスクアクセス」を選択<br>3. 使用しているアプリ（例：Automator.app、ChatGPT.app、または実行中のスクリプトランチャー）を追加してオンにする</strong></p>



<p>この設定を行うと、ブラウザ・PDF・Word・メモなど、<br>どのアプリ上でもクイックアクションを安定して利用できるようになります。<br>特にAutomator経由でスクリプトを動かす場合は「Automator.app」へのアクセス許可が重要です。</p>



<h4 class="wp-block-heading">■ TextEditでクイックアクションが出てこない場合</h4>



<p>TextEditでテキストを選択しても、右クリックメニューにクイックアクションが表示されない場合があります。<br>これは、TextEditがリッチテキスト（装飾付き）モードになっているとAutomatorが対象外とみなすためです。</p>



<p><strong>&#x1f4a1; 対処方法：<br>1. メニューの「フォーマット」→「標準テキストにする（⌘⇧T）」を選択し、プレーンテキストモードに切り替える。<br>2. 再度右クリック → 「クイックアクション」を確認。</strong></p>



<p>すると、「ChatGPT要約付きTXT保存」などのワークフローが表示されます。</p>



<h4 class="wp-block-heading">&#x2699;&#xfe0f; Automatorの設定で特に重要なポイント！</h4>



<p>Automatorでクイックアクションを作成するときは、<br>上部の設定欄にある</p>



<p>「ワークフローが受け取る現在の項目」</p>



<p>の指定を 必ず「テキスト」に設定してください。<br>ここが「リッチテキスト」や「ファイル」のままだと、<br>TextEditではメニューに表示されません。</p>



<p><strong>正しい設定：<br>• ワークフローが受け取る現在の項目：&#x1f7e2;「テキスト」<br>• 使用できるアプリケーション：&#x1f7e2;「任意のアプリケーション」</strong></p>



<p>この設定を間違えると、メモでは動くのにTextEditでは出ない、という現象が起こります。</p>



<p>&#x1f538;ポイント：Automatorの「受け取る項目」は“入力タイプの宣言”に相当します。<br>TextEditがプレーンテキストを出すときだけ、この条件に一致します。</p>



<h4 class="wp-block-heading">&#x1f9ed; Stream Deckでの活用（おすすめ）</h4>



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



<p>クイックアクションも十分便利ですが、Stream Deckを持っている方は、こちらを使うのがおすすめです。</p>



<p>Stream Deckは、右クリックメニューではなくAppleScriptやShellスクリプトを直接起動できるランチャーです。<br>そのため、ChatGPTアプリのようなWebView上のテキストでも問題なく実行できます。<br>つまり、どんなアプリや画面上でも「コピー → ボタン一発」で要約＋保存が可能になります。</p>



<p><strong>&#x25b6; Stream Deckでの設定例<br>1. Stream Deckアプリを開く<br>2. 「System」→「Open」または「AppleScript実行」アクションを追加<br>3. あなたのスクリプトファイル（例：Save_Clipboard_with_Summary.scpt）のパスを指定<br>4. ボタンに「要約して保存」などの名前やアイコンを設定</strong></p>



<p>これで、どんなアプリ上でも：</p>



<p>テキストをコピー → Stream Deckボタンを押す → ChatGPTが自動要約 → Dropboxに保存<br>という流れをワンアクションで実行できます。</p>



<p><strong>&#x25b6; 併用のすすめ<br>• 普段は右クリックのクイックアクションで十分<br>• ChatGPTアプリやPDFなど、クイックアクションが反応しない場合はStream Deckで実行</strong></p>



<p>両方に同じスクリプトを指定しておけば、操作感を統一しつつ、どんな環境でも動く構成になります。</p>



<h4 class="wp-block-heading">■ 利用のポイント</h4>



<p><strong>• 無料版（GPT-3.5）でも問題なく動作します。<br>• 英語記事や長文を正確に要約したい場合は、GPT-4またはGPT-5（ChatGPT Plus）を推奨。<br>• すべてローカルで完結し、外部通信やAPI設定は不要。<br>• 要約と手入力タイトルのどちらにも対応し、ファイルは日時順に整理されます。</strong></p>



<h4 class="wp-block-heading">■ 応用例</h4>



<p>プログラミングスクリプトの日本語要約もさることながら、</p>



<p>•<strong> 英語→日本語要約版<br>• 翻訳＋保存版<br>• URL要約版(&#x1f449;「質問してみましょう」のボックスにURLが入った状態で待ちになる場合は、右のボタンを押して動作させる)</strong></p>



<p>ChatGPTアプリを直接操作する感覚で自動化できるため、<br>誰でもすぐに試せる実用的なAI活用法です。<br>Macユーザーなら今日からすぐ導入できます。</p>



<p>以上<br><br></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">27668</post-id>	</item>
		<item>
		<title>【Mac】Dropboxリンクに一致するフルパスを見つける発見的方法</title>
		<link>https://imakat.com/2025/08/07/26878/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Thu, 07 Aug 2025 13:03:57 +0000</pubDate>
				<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[シェルスクリプト]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=26878</guid>

					<description><![CDATA[課題： Dropboxリンクを使って画像や動画をWordPressなどのブログに貼り付けることはできますが、意外とやっている人は少ないです。その理由はいくつかあると思いますが、一番大きな理由は、Dropboxリンクの文字 [&#8230;]]]></description>
										<content:encoded><![CDATA[<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=55" 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=zPkM9gDH.png" playsinline preload="metadata" style="width:100%;height:auto;">  <source src="https://imakat.com/rd.php?id=6GP8yuht.mp4" type="video/mp4">  <track src="https://imakat.com/rd.php?id=FnZSmvnF.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>) (1)〜Dropboxリンクに一致するフルパスの検索〜<br>
(<a href="#" class="imk-cue" data-seek="0:11">00:00:11</a>) (2)アプリ「dropboxリンクに一致するフルパス検索.app」を起動します。<br>
(<a href="#" class="imk-cue" data-seek="0:17">00:00:17</a>) (3)Dropboxの共有リンクを入力します。<br>
(<a href="#" class="imk-cue" data-seek="0:27">00:00:27</a>) (4)前もって用意した、Dropboxリンクのサンプルを使います。<br>
(<a href="#" class="imk-cue" data-seek="0:38">00:00:38</a>) (5)ペーストします。 https://www.dropbox.com/scl/fi/7l9*************tqn50/130606_.jpg?rlkey=8i2wf85**************cxw&raw=1<br>
(<a href="#" class="imk-cue" data-seek="0:47">00:00:47</a>) (6)この例では、ファイル名から日本語を除いた部分が「130606_.jpg」となるフルパスを検索します。<br>
(<a href="#" class="imk-cue" data-seek="1:04">00:01:04</a>) (7)一致したファイルパス： /Volumes/NO3_SSD/Dropbox/dropbox_1/pmedia/130606_刺身は大丈夫か.jpg<br>
(<a href="#" class="imk-cue" data-seek="1:15">00:01:15</a>) (8)なぞって右クリック→サービス→Finderに表示<br>
(<a href="#" class="imk-cue" data-seek="1:24">00:01:24</a>) (9)目的のファイルがハイライトされています。<br>
(<a href="#" class="imk-cue" data-seek="1:28">00:01:28</a>) (10)画像は「130606_刺身は大丈夫か.jpg」<br>
(<a href="#" class="imk-cue" data-seek="1:32">00:01:32</a>) (11)ここは、ジャカルタの郊外、　<br>
(<a href="#" class="imk-cue" data-seek="1:35">00:01:35</a>) (12)韓国の焼肉屋の、<br>
(<a href="#" class="imk-cue" data-seek="1:38">00:01:38</a>) (13)刺身の盛り合わせ。<br>
(<a href="#" class="imk-cue" data-seek="1:41">00:01:41</a>) (14)常夏の国で、刺身なんか大丈夫か。<br>
(<a href="#" class="imk-cue" data-seek="1:43">00:01:43</a>) (15)と心配になりますが、腹痛になったことはなかったです。<br>
(<a href="#" class="imk-cue" data-seek="1:46">00:01:46</a>) (16)すみません。どうでもいい話。<br>
(<a href="#" class="imk-cue" data-seek="1:49">00:01:49</a>) (17)以上です。<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>



<h5 class="wp-block-heading">課題：</h5>



<p>Dropboxリンクを使って画像や動画をWordPressなどのブログに貼り付けることはできますが、意外とやっている人は少ないです。その理由はいくつかあると思いますが、一番大きな理由は、Dropboxリンクの文字列を見たときに、例えば以下のような画像ファイルの文字列を見たときに、</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td><a rel="noopener" target="_blank" href="https://www.dropbox.com/scl/fi/55w8bp7q9758j9oktwy1q/2508083_-dropbox.png?rlkey=qp7y19s1brlh7s08hteiwhyj8&amp;raw=1">https://www.dropbox.com/scl/fi/55w8bp7q9758j9oktwy1q/2508083_-dropbox.png?rlkey=qp7y19s1brlh7s08hteiwhyj8&amp;raw=1<span class="fa fa-external-link external-icon anchor-icon"></span></a></td></tr></tbody></table></figure>



<p><br>これだけでは、その画像ファイルが自分のMac,PCのどこにあるのか全くわからない。さらにDropboxフォルダのどこにあるのかもわからない。迷子になるからです。</p>



<p>つまり、後になってその画像や動画を修正したい時、ローカルにあるファイルがすぐに見つからないという壁にぶつかってしまうのです。というか、安全対策上、ある場所をマル見せしない、それが基本ではありますが。</p>



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



<p>※正しくいうと、Dropboxの場合、おうちはDropboxのクラウドストレージ、出先がローカルフォルダ、という関係になります。ですから、エラーが続くからといって、Dropboxのクラウド側を空っぽにして、ローカルのファイルを送り込むようなことをするのは大間違いです。Dropboxリンクは全て新しいものに置き換わってしまいます。<strong>正しくは、いつも、ローカル側を空にして、クラウドストレージ側からダウンロードします</strong>。</p>



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



<p>その対処ですが、３つ考えられます。</p>



<p>１つ目は、ローカルで常に記録することです。</p>



<p>つまり、Dropboxリンクを取得するときに、そこに紐づくファイルパス（フルパスで）を記録しておくようにします。さらに、その後でファイルの名前を変えたり、フォルダを変更したりすることがあります。したがって、変更前のファイルパスと変更後のファイルパスをペアで記録しておくようにします。ローカルで確実に管理できますね。</p>



<p>２つ目は、Dropbox APIを利用する方法です。</p>



<p>Dropbox APIを使うと、Dropboxリンク及びローカルにあるDropboxフォルダ以下のパスがペアで取得できます。この情報を使って照合します。</p>



<p><strong>３つ目は、正確さは欠けますが、発見的方法（ヒューリスティック・アプローチ）です。</strong></p>



<p>そこまで丁寧な方法ではなくて、ざっくりと推測する、候補を複数ピックアップする、それだけでもかなり有用です。</p>



<p>APIを使わずに、</p>



<p>「すでにMac上にあるDropboxフォルダ内の実ファイルと照合する」だけでも、かなり役に立ちます。</p>



<p>今回は、一番シンプルな、この３つ目の方法を紹介します。</p>



<h5 class="wp-block-heading">手順：</h5>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>[考え方]<br>Dropbox APIは使わず、すでにMac上にあるDropboxフォルダ内の実ファイルと照合する、発見的方法です。<br>Dropboxリンクは、&#8221;***/<span class="bold-red">********</span>?rlkey=*******&amp;raw=1&#8243;における/と?に挟まれた<span class="bold-red">赤字</span>の部分に、ファイル名から日本語文字列を削除した部分が残されています。ローカルの対象フォルダの中のファイル名の日本語文字列を削除した部分と一致するものを抽出する方法です。<br><br><strong>AppleScriptのアプリで、以下のような手順を行うようにします。<br>（１）Dropbox共有リンクの入力を受け付ける<br>（２）そのURLから、共有リンクに埋め込まれたファイル名（dropboxStyleName）を抽出する<br>（３）Macのローカルディスク（Dropboxと同期されているフォルダ）内のファイルを find コマンドで検索し、<br>（４）ファイル名を変換（日本語文字を &#8211; に）して、dropboxStyleName と一致するかどうかを照合する<br>（５）一致したファイルの ローカルパス をリストアップして表示する<br>以上</strong></td></tr></tbody></table></figure>



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



<h5 class="wp-block-heading">スクリプト：</h5>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>AppleScript<br><strong>dropboxリンクに一致するフルパス検索.app</strong><br>下欄のスクリプトをコピペしてください。<br><span class="bold-blue">青字</span>の部分は、自分の条件に置き換えてください。<br></td></tr><tr><td>&#8212; ▼ 対象フォルダ、２つある場合です（サブフォルダも含めて検索）<br>set folder1 to &#8220;<span class="blue"><span class="bold-blue">/Volumes/NO3_SSD/Dropbox/********/********</span></span>&#8220;<br>set folder2 to &#8220;<span class="bold-blue">/Volumes/NO3_SSD/Dropbox/********/********</span>&#8220;</td></tr><tr><td><a href="https://imakat.com/?pubtxt=dropboxリンクに一致するフルパス検索app_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>



<h5 class="wp-block-heading">結果：</h5>



<p>ファイル名に、日本語を多用している場合は、複数の候補が表示されるようになっています。しかし、ファイル名には日付や連番、バージョンなどの英数字を含めるように気を配れば、複数の候補がある場合は、非常に少ないでしょう。したがって、今回の紹介の方法は、実用的であると思います。<br></p>



<p>以上</p>



<p></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">26878</post-id>	</item>
		<item>
		<title>【自宅web】メディアを短縮URLで配信する</title>
		<link>https://imakat.com/2025/02/06/25279/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Thu, 06 Feb 2025 06:31:32 +0000</pubDate>
				<category><![CDATA[マイライブラリ]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[短縮URL]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=25279</guid>

					<description><![CDATA[はじめに 自宅webサーバーの作り方については、以前の投稿でも説明しました。その中でも触れたように、自宅サーバーは、かつてブームになったものの衰退した歴史があるわけで、その衰退の理由に、主に、コストメリットが低いこと、災 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h4 class="wp-block-heading">はじめに</h4>



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



<p>自宅webサーバーの作り方については、<a href="https://imakat.com/2020/09/03/10444/" target="_blank">以前の投稿</a>でも説明しました。その中でも触れたように、自宅サーバーは、かつてブームになったものの衰退した歴史があるわけで、その衰退の理由に、主に、コストメリットが低いこと、災害に弱いことが挙げられます。しかし、そうしたデメリットを取り除いてみれば、DIYで産直配信を行うことの楽しさは相変わらずあるわけです。</p>



<p>よくメリット、デメリットを比較してデメリットが大きいので、やめてしまうことがあります。費用対効果、効果より費用が大きいのでやめてしまうことがあります。しかし、今後費用は下がる、今後デメリットは減ることが見通せるならどうでしょう。あるいは費用には労働力も入るわけですが、自分が頭や手足を使うことで出費が減らせる、あるいは、そうした作業が趣味や楽しみに転換できるなら、一挙両得という話になります。</p>



<p></p>



<p>2020年頃からそこへ、AppleシリコンMacMiniという、低電力高性能、常時稼働向きの、周辺機器なしの見た目サーバーのコンピュータが登場しました。しかも非常に小さくなってきました。コンビを組むNASも大容量のSSDが挿せるようになりどんどん小型化してきています。<a rel="noopener" target="_blank" href="https://www.gdm.or.jp/crew/2024/1002/556934">注目する技術→&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<p>明るい光を感じますね。</p>



<h4 class="wp-block-heading">クラウドにするだけでなくポータブルにする</h4>



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



<p>それで将来イメージを見通すと。。キャンピングカー、移動販売車のようになるだろうと。</p>



<p>MacMiniがもっと小さくなる。NASがもっと小さくなる。一緒に持ち運べるようになる。</p>



<p>そう。NASとMacMiniへwebサーバーとファイル管理を積み込むのは、今はまだ自宅に固定された大袈裟なサーバーです。だからクラウドストレージの方が優れていると直ぐに思ってしまいます。しかし、バッテリー駆動のポケットサイズ、ポータブルにできれば、災害にも強いです。問題は解決します。技術的にそれほど難しくはないでしょう。</p>



<p>ですから、自宅サーバーの構造思想は廃れるものではない、そう思えてくるのです。</p>



<p>さて、そんな枠組みの中で、今回の小さなテーマは、「短縮URL」作りです。</p>



<h4 class="wp-block-heading">再生用URL 4種類</h4>



<p>(A)</p>



<p>Dropboxリンク型　</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">https://www.dropbox.com/scl/fi/3qe8a289x8xx15prpu8wi/_test.png?rlkey=16oocsjxwqe594xhr68z8z67x&amp;raw=1</td></tr></tbody></table></figure>



<figure class="wp-block-image size-large"><a rel="noopener" target="_blank" href="https://www.dropbox.com/scl/fi/3qe8a289x8xx15prpu8wi/_test.png?rlkey=16oocsjxwqe594xhr68z8z67x&amp;raw=1"><img decoding="async" src="https://www.dropbox.com/scl/fi/3qe8a289x8xx15prpu8wi/_test.png?rlkey=16oocsjxwqe594xhr68z8z67x&amp;raw=1" alt=""/></a></figure>



<p></p>



<p>(B)</p>



<p>自宅サーバーパス記述型&nbsp; 日本語を直接解読できないのでエラーになる。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">https://imakat.synology.me/wp-content/pmedia/これはテストです_test.png</td></tr></tbody></table></figure>



<figure class="wp-block-image size-large"><img decoding="async" src="tbody https://imakat.synology.me/wp-content/pmedia/これはテストです_test.png" alt=""/></figure>



<p></p>



<p>(C)</p>



<p>日本語エンコード型　</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">https://imakat.synology.me/wp-content/pmedia/%E3%81%93%E3%82%8C%E3%81%AF%E3%83%86%E3%82%B9%E3%83%88%E3%81%A7%E3%81%99_test.png</td></tr></tbody></table></figure>



<figure class="wp-block-image size-large"><a rel=" noopener" target="_blank" href="https://i0.wp.com/imakat.synology.me/wp-content/pmedia/%E3%81%93%E3%82%8C%E3%81%AF%E3%83%86%E3%82%B9%E3%83%88%E3%81%A7%E3%81%99_test.png?ssl=1"><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/imakat.synology.me/wp-content/pmedia/%E3%81%93%E3%82%8C%E3%81%AF%E3%83%86%E3%82%B9%E3%83%88%E3%81%A7%E3%81%99_test.png?w=1256&#038;ssl=1" alt=""/></a></figure>



<p>(D)</p>



<p>「画像ライブラリー作成」を行なって、外部サーバー短縮型URLを作る</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">https://imakat.com/rd.php?id=HAbEMjIY.png</td></tr></tbody></table></figure>



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



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



<p><s>(E)</s></p>



<p><s>マッピング更新を行って、自宅サーバー短縮型URLを作る。</s></p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc"><s>https://imakat.synology.me/3zqfq8nn.png</s></td></tr></tbody></table></figure>



<figure class="wp-block-image size-large"><a rel=" noopener" target="_blank" href="https://i0.wp.com/imakat.synology.me/3zqfq8nn.png?ssl=1"><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/imakat.synology.me/3zqfq8nn.png?w=1256&#038;ssl=1" alt=""/></a></figure>



<p>以上4種類がありますが、(B)は表示が不可能になりやすいので除くと3種類になります。</p>



<p>この中で、WordPress投稿内で使用するのに適しているのは、どれか。</p>



<p>それは、(D)です。</p>



<p>この3種類の中で、動的URLは(D)だけです。カートリッジ型です。</p>



<p><strong>それで(D)を採用しました</strong>。</p>



<p>なお、配信サーバーの切り替えについては、別の投稿で説明します。</p>



<p></p>



<h4 class="wp-block-heading">ランダム文字列の扱い</h4>



<p>ところで、この8桁のランダム文字列ですが、1234e678などの数字とeで構成されていると、数字と解釈されてしまいます。openssl rand -hex4と記述すると、1234e678のような科学表記になる可能性があります。cat /dev/urandom | tr -dc &#8216;a-zA-Z0-9&#8217; | fold -w 8 | head -n 1を使って、英数字混合にすることで純粋な文字列として扱うことにしました。</p>



<p></p>



<p>以上です。<br><br></p>



<p></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">25279</post-id>	</item>
		<item>
		<title>【WordPress】「画像ライブラリ」を作ってみた。〜動画画像ライブラリ3〜</title>
		<link>https://imakat.com/2025/01/08/24997/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Wed, 08 Jan 2025 05:24:47 +0000</pubDate>
				<category><![CDATA[マイライブラリ]]></category>
		<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[GAS]]></category>
		<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[JSON]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=24997</guid>

					<description><![CDATA[動画画像ライブラリー第３弾です。 Dropboxリンクは目立たないようにしたい。 これまで画像のURLリンクもDropboxを使えばいいと考えていて、Finderで右クリックして「Dropboxリンクをコピー」で得られた [&#8230;]]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large is-resized"><a href="https://imakat.com/rd.php?id=DUFdyZAj.png" target="_blank"><img decoding="async" src="https://imakat.com/rd.php?id=DUFdyZAj.png" alt="" style="width:171px;height:auto"/></a></figure>



<p>動画画像ライブラリー第３弾です。</p>



<h5 class="wp-block-heading">Dropboxリンクは目立たないようにしたい。</h5>



<p>これまで画像のURLリンクもDropboxを使えばいいと考えていて、Finderで右クリックして「Dropboxリンクをコピー」で得られたリンクを、そのリンクの末尾のdl=0をraw=1に置き換えて使えば、それだけでいい。そのように思ってきました。</p>



<p>Dropboxリンクの例は、下のようになります。</p>



<p>(A)</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">https://www.dropbox.com/scl/fi/xxxxxxxxxx/v3_imakat.png?rlkey=xxxxxxxxxx&amp;raw=1</td></tr></tbody></table></figure>



<p>このDropboxリンクが安全性に優れている点は、クリックしてから実際に再生する時は更に<strong>ワンタイムトークンリンクに変換されてからブラウザで再生されます</strong>。(B)のように形を変えます。ブラウザへURLをコピペするとこうなります。しかもこのURLは一定の時間が経過すると無効になります。</p>



<p>(B)</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">https://uce9dafc269d365818926846419f.dl.dropboxusercontent.com/cd/0/inline/Chthco4Tzn_2sCYS-ARStjz7FpZwTL9NkufD8Tw7M9-_bhwZ_g2zr2Qpz438qIwJbXdcAGwNaCcLlodnarQYoFRBZ9CrxJbNUHldMJX15qcEWuIQ1oz_T3QPgWrfmc-gB74/file#</td></tr></tbody></table></figure>



<p>WordPressの画像ブロック→URLから挿入→(A)を挿入→HTMLとして編集を選ぶと、以下のコードが記述されています。</p>



<p>(C)</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">&lt;figure class=&#8221;wp-block-image size-large&#8221;&gt;&lt;img src=&#8221;https://www.dropbox.com/scl/fi/xxxxxxxxxx/v3_imakat.png?rlkey=xxxxxxxxxx&amp;raw=1&#8243; alt=&#8221;&#8221;/&gt;&lt;/figure&gt;</td></tr></tbody></table></figure>



<p>これで構わないとすれば、それまでのことですが、ブラウザからページのソースを読めば、上のコードは丸見えになります。Dropboxとすれば、(A)の情報が知れ渡るのは、あまり嬉しくないでしょう。「頭隠して尻隠さず」状態ということですからね。</p>



<p>そこで、以下のように、AppSheetで、動的な画像サイトを作ることにしました。</p>



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



<p>(D)</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">https://imakat.com/rd.php?id=57fYUfLE.png</td></tr></tbody></table></figure>



<p>これを、画像ブロック→「URLから挿入」に入れます。こうすると、(A)の部分は、WordPressに表示されなくなります。(C)から分かるように、メディアはDropboxから読み込んでいるのですが、読者からは、どこから読み込まれているのか分かりません（そのようにしたいわけです)。</p>



<h5 class="wp-block-heading" id="alternative-url">簡単に代替URLへ移行したい。</h5>



<p>画像ライブラリ(D)を作るもう一つの目的が、 メディアのソースを、DropboxリンクからXserver、pCloudなど他のサーバーへ、簡単に、切り替えられるようにすることです。</p>



<p>なぜって？やはりDropboxにもトラブルは起こりうるからです。</p>



<p>こうした移行は、一般的には、プラグインを使って、WordPressのソースに書き込まれているURLを、直接に、置き換える方法が取られると思います。</p>



<p>しかし、ソースにDropboxリンクを使っている場合はそうはいきません。Dropboxリンクはファイル名やローカルパスが外から分からないようにランダム文字列に置き換えられていますので、ローカルパスだけをサクッと置き換えることは出来ないのです。</p>



<p>1点1点、Dropboxリンクと自宅サーバーURLを対応させた、マッピングファイルを作成する必要があります。丁寧にいうと、DropboxリンクとローカルパスとXserverサーバーURLの3つをマッピングさせたレコードを作成する、それをファイル上で右クリックしてあといくつかのクリック操作だけで済むようにしているところが、ポイント解説にて紹介するAppleScriptの特徴です。</p>



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



<p>そしてこのマッピングファイル(Google spreadsheet)をJSONファイルとして、WordPressに送り込むようにします。マッピングファイルの更新は1日一回夜中に行います。</p>



<p><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1FfdLcASztqVWOvbtehhBqTKn300ae0-SbJmNPa9CrlI/edit?usp=sharing">link_mapping.csvの重複レコードの整理について&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<p>ここまで書いてきて、私が、動的サイトの使いやすさにこだわる理由が分かっていただけたでしょうか。</p>



<p>それでは次は、ポイント解説です。</p>



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



<p>すみません。説明で使う素材を2024-11-28_15.50.35.pngに変更します。</p>



<h4 class="wp-block-heading">1 画像ライブラリ作成AppleScript</h4>



<p><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1dvudjxR_FGNqNm4XmaA0M4ohwWtO7ovHtxn5GFKFre4/edit?usp=sharing">画像ライブラリ作成 AppleScript&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<p>Dropboxリンクをコピーした後に、クイックアクションの中から「画像ライブラリー作成」を選びます。</p>



<p>ポイントは、必ず「Dropboxリンクのコピー」を行った後で、クイックアクションに入り、「画像ライブラリ作成」を選ぶことです。いきなりクイックアクションに入ると、その段階では、古いクリップボードが残ったままになっています。</p>



<p>そこで、一応、ポカよけとして、以下をメッセージ表示します。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">cutjp_fileName: 2024-11-28_15.50.35.png<br>【注意】Dropboxリンクのコピーが行われていない可能性があります。再度Dropboxリンクのコピーを実行してください。</td></tr></tbody></table></figure>



<p>ここはひとまずOKを押して終了します。</p>



<p>改めて、Dropboxリンクのコピーを実行した後で、クイックアクションの「画像ライブラリ作成」を選ぶと、<br></p>



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



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">https://www.dropbox.com/scl/fi/xxxxxxxxxx/_2024-11-28_15.50.35.png?rlkey=xxxxxxxxxx&amp;dl=0<br>に関するデータを、csvファイルの1行として追加します。</td></tr></tbody></table></figure>



<p>と表示されます。</p>



<p>ここでOKを押せば行追加が実行されます。</p>



<h5 class="wp-block-heading">日本語のファイル名の時の注意喚起</h5>



<p>ファイル名に日本が混じる時、Dropboxリンクは日本語は削除されます。リンクはランダム文字列で作られますので、日本語が削除されてもユニークなリンクにはなりますが、日本語だけで出来たファイル名ですと、リンクを見ても、どのファイルか、想像すら出来ません。特に、複数の日本語だけのファイルが続きますと、どこまで処理したか、分からなくなります。そこで、日本語だけのファイル名を扱う時は、必ず、Dropboxリンクの取得が済んでいるか注意喚起をします。</p>



<p><a href="https://imakat.com/rd.php?id=CrEUQkyo.png" target="_blank">日本語のファイル名の時の注意喚起&#x1f4f7;</a></p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td style="background-color:#fff7cc">https://www.dropbox.com/scl/fi/xxxxxxxxxx/.png?rlkey=xxxxxxxxxx&amp;dl=0は、ファイル名が全て日本語のため、Dropboxリンクのコピーが済んでいるか否かが判別できません。自信がない場合は、キャンセルを押して、リンクのコピーを再実行ください。自信があればOKを押してcsvを追加ください。</td></tr></tbody></table></figure>



<p>ただ、出来れば日本語だけのファイル名は避けるのがいいです。</p>



<p>AppleScriptの中では、wp_photo_library.csvへ行を追加しています。更に、link_mapping.csvにも行を追加します。</p>



<h4 class="wp-block-heading">2 追加したデータをWordPressで扱えるようにする</h4>



<p><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/17xQcuavGDB4SXsbn0ygwQcRk46JnLohn3M6fXp37LzE/edit?usp=sharing">importAndBackupCSV GAS&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<p><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1odAmk9t8fq3GX1q0ZPwLyzWtv3kGiZcO8n3IRRxeKhw/edit?usp=sharing">createPhotoJson GAS&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<p><a rel="noopener" target="_blank" href="https://docs.google.com/document/d/1VeQ6Hl6mzJeh5sdHU2v7FTdeYAqBGrCS2JyUE98Cums/edit?usp=sharing">im.php JSONから画像を表示　php&#x1f4c4;<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<p>画像ライブラリ用のデータは、クイックアクションでwp_photo_library.csvに追記されます。このデータを動画画像idのシート3に書き込みます。ファイルURLおよび画像idはユニークです。シート3へ書き込んだ後、wp_photo_library.csvにあったデータは、backup_wp_photo_library.csvへ追記した後、wp_photo_library.csvはクリアします。新たに作った画像サイトは、今作業中のブログにすぐに使いたいので、１分おきの更新にします。</p>



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



<p>少し待ちますが、新たに登録された場合は、AppSheetの動画画像ライブラリの画像メンテの先頭に、情報が表示されます。この中から、再生URLを取得して、WordPressの画像ブロック→URLから挿入するなど、利用します。</p>



<p></p>



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



<p>このシリーズは、３回までで動画および画像を外部から読み込んで表示する方法、動的サイトの構築について説明してきました。次のシリーズでは、Dropboxリンクから複数のサーバーへ切り替える方法について、紹介します。</p>



<p>以上です。<br><br></p>



<p></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">24997</post-id>	</item>
		<item>
		<title>Xserverにあるデータをローカルへ自動定期バックアップする(SFTP、SSH接続)</title>
		<link>https://imakat.com/2024/11/24/24352/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Sun, 24 Nov 2024 05:29:53 +0000</pubDate>
				<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Xserver]]></category>
		<category><![CDATA[Transmit5]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[SFTP]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=24352</guid>

					<description><![CDATA[2024.12月から、一番下のまとめに書いた、Xserver内に圧縮zipファイルを作成する→次にMacのrsyncでダウンロードする方法へ移行しています。 はじめに 今回は、SynologyNASとMac miniのフ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>2024.12月から、一番下のまとめに書いた、<a href="https://imakat.com/?pubtxt=xserver内に圧縮zipを作成_pub.txt" target="_blank">Xserver内に圧縮zipファイルを作成する</a>→<a href="https://imakat.com/?pubtxt=rsync_xserverからdropboxへダウンロード_pub.txt" target="_blank">次にMacのrsyncでダウンロードする</a>方法へ移行しています。</p>



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



<p><strong>はじめに</strong></p>



<p>今回は、SynologyNASとMac miniのファイル管理システムにおいて、下の赤枠で囲んだ部分について紹介します。AppleシリコンのMac miniを常時稼働してサーバーのように使う人が、これからどんどん増えるように思えます。そうなってくると、今回紹介するミニシステムは、定番の一つになると想像します。</p>



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



<p><strong>Xserverにあるデータをローカルへバックアップする(SFTP、SSH接続)</strong></p>



<p>Xserverは、契約すれば無料で１週間分のバックアップがついてくるから、なんでわざわざローカルにバックアップなんか必要なの？</p>



<p>そのような疑問は確かに起こります。</p>



<p>Xserverの無料バックアップからの復元は、復元を申請したあとに心配がおきます。つまり、いつ処理が開始していつ頃終了するのか分からないので、ただ待つしかないのです。私の経験からは30分で済むこともあれば3時間かかることもあります。時間が読めないこと、それは結構ストレスです。またその時間を大幅に短縮したいです。出来れば10分以内。そのためには、前夜の状態のファイルがローカルにバックアップされていれば大丈夫でしょう。そのバックアップするフォルダは、WordPressのフォルダが対象なので、uploadsとthemesがあれば十分でしょう。</p>



<p>以前に、Transmit5のFTPを使ってXserverへアップロードする方法を紹介しましたが、今回は、Transmit5のSFTPすなわちSSH接続を使って、Xserverからダウンロードを行う方法、しかもそれを自動運転にする方法を紹介します。</p>



<p>なかなかMacを使ったSFTP、SSH接続の日本語での解説ブログやYouTubeは見当たりませんね。</p>



<p>５手順と長くなりますが、よろしくお付き合いください。</p>



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



<h4 class="wp-block-heading"><strong>手順１ 　XserverのSSH接続を開通させる</strong></h4>



<p><strong>（１）　MacでSSHキーを作成</strong><br>以下を行うと、id_rsa（秘密鍵）とid_rsa.pub（公開鍵）が作成されます。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>ssh-keygen -t rsa -b 4096 -C &#8220;your-email@example.com&#8221;</td></tr></tbody></table></figure>



<p><strong>（２）　公開鍵をXserverに登録</strong></p>



<p>id_rsa.pubの内容をコピーして、Xserverの管理画面に登録します。</p>



<p>１）id_rsa.pubは、隠しファイルになっているので、Finderの右上の虫眼鏡にid_rsa.pubと入れて、見つけてください。それを、テキストエディット.appで開く→内容をコピー。</p>



<p>２）Xserverのサイトに入る→サーバーパネル→SSH設定をON</p>



<p>&nbsp;初期設定の段階なので、とりあえず「ON[すべてのアクセスを許可] 」を選択します。<br>※2024/11/25現在、国内からのアクセスのみ許可に変更</p>



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



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



<p><strong>（３）公開鍵登録・更新</strong>→（２）１）でコピーした公開鍵をペースト→確認画面へ進む→登録する。</p>



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



<p><br><br><strong>（４）　接続の確認</strong></p>



<p>ターミナルへ以下を入れて接続してください。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>ssh -i ~/.ssh/id_rsa -p 10022 your-username@your-server</td></tr></tbody></table></figure>



<p>Xserverの場合、</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>ssh -i ~/.ssh/id_rsa -p 10022 your-username@your-username.xsrv.jp</td></tr></tbody></table></figure>



<p>となります。</p>



<p>接続が成功したら、一旦、ターミナルはexitを入れて終了してください。</p>



<h4 class="wp-block-heading"><strong>手順２　Transmit5アプリを使って、SFTPにて、単独でバックアップできるようにする</strong></h4>



<p>赤く消してあるところは、ユーザ名が入ります。１（１）で作成した秘密鍵、id_rsa、を、パスワードまたはキーの右側のキーのアイコンをクリックして認証鍵を入れるボックスを開き、その中に登録します。登録は、このボックスの下にある＋のマークをクリックすると、親切に通常は非表示のフォルダも表示されてid_rsaが選択出来ます。登録されたらid_rsaの上をタップすると、キーに収まります。<br>XserverにおけるSSH設定の条件は<a rel="noopener" target="_blank" href="https://www.xserver.ne.jp/manual/man_server_ssh.php">ここに<span class="fa fa-external-link external-icon anchor-icon"></span></a>記載されています。</p>



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



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



<p>上と同様に、SFTP_uploadsも作成します。<br><br></p>



<h4 class="wp-block-heading"><strong>手順３　バックアップ用のアプリを作る</strong></h4>



<p>上で作った単独バックアップを起動させて動作した後に終了する流れを、Automatorで一つのアプリとして作成します。まず、SFTP_themesは以下です。</p>



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



<p>Automatorで新規作成→アプリケーションを選び、Transmit.appを選びます。接続先の選択肢にTransmit5にお気に入り登録したものが出てくるので、SFTP_themesを選びます。すると、サーバ、ユーザ名、パスワード、ポート、プロトコルは、引っ張ってきて入ります。それ以下の項目は設定します。</p>



<p><strong>同期の方向：ダウンロード（今回の場合はダウンロードです。ここは要注意！！）</strong></p>



<p>比較の方法：変更日</p>



<p>スキップ項目：なし</p>



<p>ローカルパス：これは、Finderで探して設定します。自分があとで扱いやすい場所。</p>



<p>オプション：同期先のみに存在する項目は削除する。（単純なバックアップ目的のダウンロードは、チェックを外します）</p>



<p>リモートパス：リモートサーバとの時差を自動で調整する。一応チェックを入れておきます。</p>



<p>処理が済んだら、Transmit5を終了→Automatorを終了します。</p>



<p>次に同様に、uploadsフォルダのダウンロードである　SFTP_uploadsも同様に設定します。このように小分けする理由ですが、ダウンロードは結構、エラーが起きやすく、あまり大きなフォルダですとやり直しに多大な時間が掛かります。ですので、例えば初期ダウンロードで１０分程度で済むサイズで区切るとか、小分けにした方がいいです。</p>



<h4 class="wp-block-heading"><strong><strong>手順４　複数の単独アプリを流れとして組む</strong></strong></h4>



<p>Automatorで作成した単独アプリを流れとして組み込みます。なお、<strong>完了の通知としてメールを使います</strong>。夜中の自動処理を設定すると、本当に処理が行われているかどうか心配になります。メール一つあるだけで安心します。</p>



<p>AppleScriptを使います。まとめたアプリをSFTP_themes_and_uploads.appとします。</p>



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>&#8212; スクリプト開始<br>on run<br>	&#8212; SFTP_themes.app を起動<br>	tell application &#8220;SFTP_themes&#8221;<br>		activate<br>	end tell<br>	<br>	&#8212; アプリが終了するまで待機<br>	delay 10 &#8212; アプリの自動終了までの目安時間（必要に応じて調整）<br>	<br>	&#8212; 1分間待機<br>	delay 70<br>	<br>	&#8212; SFTP_uploads.app を起動<br>	tell application &#8220;SFTP_uploads&#8221;<br>		activate<br>	end tell<br>	<br>	&#8212; アプリが終了するまで待機<br>	delay 10 &#8212; アプリの自動終了までの目安時間（必要に応じて調整）<br>	<br>	&#8212; メールを作成して送信<br>	tell application &#8220;Mail&#8221;<br>		set newMessage to make new outgoing message with properties {subject:&#8221;SFTP_themes_and_uploadsは完了しました。&#8221;, content:&#8221;M1 Mac自動処理&#8221;, visible:false}<br>		tell newMessage<br>			make new to recipient at end of to recipients with properties {address:&#8221;xxxxxx@gmail.com&#8221;}<br>			send<br>		end tell<br>	end tell<br>end run</td></tr></tbody></table></figure>



<h4 class="wp-block-heading"><strong><strong><strong>手順５　自動処理させるために、カレンダーに組み込む</strong><br><br></strong></strong></h4>



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



<p>Macのカレンダーには、「通知」の機能の中にあるカスタムに、「ファイルを開く」がありここでアプリを起動することができます。</p>



<p>カレンダーからは、アプリは起動するだけで、終了の動作は行いません。終了の動作は、取り付けるアプリの中に組み込まれている必要があります。</p>



<p>開始：日時</p>



<p>終了：日時　ここは、時刻は開始時刻と同じで構いません。</p>



<p>繰り返し：毎日</p>



<p>繰り返し終了：なし</p>



<p>移動時間：なし</p>



<p>通知：カスタム</p>



<p>ファイルを開く　SFTP_themes_and_uploads.app これはアプリケーションフォルダから選択、予定の開始時刻を選択</p>



<p>次に、</p>



<p>Macのシステム設定→プライバシーとセキュリティ→カレンダー→SFTP_themes_uploadsのオプションからフルアクセスにする→カレンダーを終了して再度立ち上げます。</p>



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



<p></p>



<p><strong>その他、まとめ</strong></p>



<p>SFTPによるダウンロードですが、禁止文字の使用など様々な理由でエラーで進まないこともあります。その場合、<strong>Xserver内で、zipファイルに圧縮してからrsyncでダウンロードする</strong>と、順調に行くことが多いです。<br><br><a href="https://imakat.com/?pubtxt=xserver内に圧縮zipを作成_pub.txt" target="_blank">Xserver内に圧縮zipファイルを作成する</a>→<a href="https://imakat.com/?pubtxt=rsync_xserverからdropboxへダウンロード_pub.txt" target="_blank">次にMacのrsyncでダウンロードする</a>方法。</p>



<p>以上が、定期的自動的に、外部サーバーにあるデータを、ローカルにダウンロードする流れになります。こうした処理が自宅で簡単に行えるようになってきたのも、Macが、特にMac miniが省電力になり、常時稼働が可能になってきたことが大きいです。</p>



<p>以上</p>



<p></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">24352</post-id>	</item>
		<item>
		<title>MacからMacを操作する〜画面共有の利用〜</title>
		<link>https://imakat.com/2024/11/17/24259/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Sun, 17 Nov 2024 07:59:09 +0000</pubDate>
				<category><![CDATA[デジタル]]></category>
		<category><![CDATA[ものづくり]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[SynologyNAS]]></category>
		<category><![CDATA[AppleScript]]></category>
		<category><![CDATA[画面共有]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=24259</guid>

					<description><![CDATA[2026.2.22：最近Macminiを常時稼働させてAIエージェントとして使うのがブームになっているようです。というか一家に一台、24時間365日稼働させる、汎用のコンピュータがある時代になったということですね。このM [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>2026.2.22：<br>最近Macminiを常時稼働させてAIエージェントとして使うのがブームになっているようです。というか一家に一台、24時間365日稼働させる、汎用のコンピュータがある時代になったということですね。このMacからMacを操作する方法はとても役にたつと思います。それから裏方のMacminiは、そんなに迅速に動いてくれる必要はありません。24時間365日使って安定して作業してくれればいいわけで、M1のMacminiでも、まだまだ十分に使えます。つまり安いです。</p>



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



<p>SynologyNASとM1 Mac miniによるファイル管理システムを動かすにあたり、前回は、Jump DesktopによるiPad iPhoneからM1 Mac miniのリモート操作を紹介しましたが、それは実は頻度は低く、実際は90%以上は、今回紹介する、画面共有によるM2 Mac miniからM1 Mac miniのリモート操作になると思います。</p>



<p>あと、いつもいつも、M2 Mac miniと書くのも面倒なこともあり、要は、「Mac」と一言で括れる共通事項については、面倒に感じた時はMacと書くようにします。小さい話です。</p>



<p>ただ、モニター、マウス、キーボードといった周辺機器が何もないのがMac miniですし、省電力になり常時稼働が平気になったのがM1以降ですので、M1 Mac miniが裸っぽの原点になります。M1以降ならMacbookなどラップトップも全てavailableなチキチキマシーンです。</p>



<p>それでは中身に入ります。</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=39" 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://www.dropbox.com/scl/fi/w8zqic0a3d8okwp3dfh7t/screenshot_2024-11-17_14.06.30.png?rlkey=mbfmdsofndrvc6cybqhnofdpd&#038;raw=1" playsinline preload="metadata" style="width:100%;height:auto;">  <source src="https://imakat.com/rd.php?id=cnN9m7vL.mp4" type="video/mp4">  <track src="https://imakat.com/rd.php?id=rcVApp2z.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>) 1) 「Macで別のMacを操作する　画面共有の利用」<br>
(<a href="#" class="imk-cue" data-seek="0:07">00:00:07</a>) 2) この図は、MacとSynologyNASの連携システムです。<br>
(<a href="#" class="imk-cue" data-seek="0:11">00:00:11</a>) 3) 今回は、その中から、この部分。M2Macから画面共有でM1Macを操作してみます。<br>
(<a href="#" class="imk-cue" data-seek="0:17">00:00:17</a>) 4) M2MacからSTREAM DECKで、画面共有を起動します。<br>
(<a href="#" class="imk-cue" data-seek="0:23">00:00:23</a>) 5) M1Macが表示されます。<br>
(<a href="#" class="imk-cue" data-seek="0:33">00:00:33</a>) 6) M2Macのメモアプリを立ち上げます。<br>
(<a href="#" class="imk-cue" data-seek="0:41">00:00:41</a>) 7) こちらはM1Macのメモアプリです。<br>
(<a href="#" class="imk-cue" data-seek="0:46">00:00:46</a>) 8) 文字を打ち込んでみます。　<br>
(<a href="#" class="imk-cue" data-seek="1:08">00:01:08</a>) 9) M2Macのメモアプリでも、当然、同期して表示されます。<br>
(<a href="#" class="imk-cue" data-seek="1:20">00:01:20</a>) 10) M1Macで文字を打ち込みます。<br>
(<a href="#" class="imk-cue" data-seek="1:27">00:01:27</a>) 11) M2 Macの表示も同じ。<br>
(<a href="#" class="imk-cue" data-seek="1:31">00:01:31</a>) 12) M2Macの文字を修正します。<br>
(<a href="#" class="imk-cue" data-seek="1:34">00:01:34</a>) 13) M1Macも同じ。<br>
(<a href="#" class="imk-cue" data-seek="1:36">00:01:36</a>) 14) 有線LAN接続ですが、遅延はほとんど感じません。<br>
(<a href="#" class="imk-cue" data-seek="1:39">00:01:39</a>) 15) 画面共有は右端に新たなデスクトップが作られます。<br>
(<a href="#" class="imk-cue" data-seek="1:42">00:01:42</a>) 16) 私の場合は、デスクトップは、一つだけでいいかも知れません。<br>
(<a href="#" class="imk-cue" data-seek="1:47">00:01:47</a>) 17) こんなふうに移動する必要もなくなります。後で削除します。<br>
(<a href="#" class="imk-cue" data-seek="1:54">00:01:54</a>) 18) 画面共有でも、ほとんど違和感なく操作ができます。<br>
(<a href="#" class="imk-cue" data-seek="1:59">00:01:59</a>) 19) 以上です。<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>



<p></p>



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



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



<p>MacからMacを操作する方法には、Appleが提供するものとしては2つあって、一つは今回の「画面共有」ですが、あと一つは「リモートマネジメント」があります。「リモートマネジメント」は本格的な方法で専用アプリが必要になります。「リモートマネジメント」は大規模な企業ネットワークでIT担当者が使用するような仕組みなので、ちょっと縁遠いです。自宅でDIYできる範囲が、私のテリトリーです。</p>



<h4 class="wp-block-heading">１　STREAM DECKの利用</h4>



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



<figure class="wp-block-flexible-table-block-table"><table class="has-fixed-layout"><tbody><tr><td>スクリプト要約：画面共有アプリを自動操作し、指定Mac（yyyyyyyy-macminim1）へ接続するAppleScript。アプリ起動後3秒待機し、メニューバーから最近接続先を選択。接続確立まで待ち、パスコード「&lt;あなたのパスワード&gt;」を自動入力してEnterを押す。その後、ウィンドウ表示を待ってフルスクリーン化する一連の手順をスクリプト化している。</td></tr><tr><td><a href="https://imakat.com/script_list/?pubtxt=M1Macの画面共有を起動する_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>STREAM DECKに画面共有を立ち上げるスクリプトを登録しています。その理由は、画面をスムーズに立ち上げるために、手順と細かいチューニングを決めておきたいからです。主なものは２点あります。</p>



<p>一つ目は、パスコードを入れる前の待ち時間のチューニングです。パスコードも自動で打ち込むようにしてあるのですが、タイミングが合わないと画面が止まってしまいます。例えて言うと、電車の出発が早すぎると、乗り遅れてホームに置き去りにされたままになってしまいます。そこで電車を遅らせます。一応delay５秒にしておきます。もちろんその、次の電車に乗ればいいわけで、つまり少々待って、もう一度自分でSTREAM DECKのボタンを押せば、大抵OKとは申せますが。</p>



<p>二つ目は、ウインドウをフルスクリーンに設定することです。その理由は、起動した最初は、ウインドウは画面上に浮いたような状態でして、これですとカーソルがウインドウの中と外を行き交うので少々脳細胞が混乱してストレスです。割り切ってウインドウをフルスクリーンにして固定した方がマウスの操作がラクです。画面共有を立ち上げると、画面共有という名のデスクトップが追加されるので他のアプリへの支障はありません。</p>



<p>細かい話になりますが、スクリプトの最後のステップに、ウインドウをフルスクリーンにするアクションがあります。その際、フルスクリーンボタンの番号は、表示場所とは必ずしも一致しない点は、記憶に留めておくと良いでしょう。現状、ウインドウのボタンは3つ並んでいます。そのうちで今回目的のフルスクリーンのボタンは右端にあります。3つあってそのうち右端なので、ふつうは、１または３だな、と思うじゃありませんか。ところが違うのですね。正解は２です。今のところ、そのような仕様になっています。試行錯誤で見つけ出すことになります。</p>



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



<p></p>



<p></p>



<h4 class="wp-block-heading">２　そのまま相手を再起動できる</h4>



<p>M1 Mac miniが重いような気がした時、再起動をしますよね。再起動ができるのです。M1 Mac mini画面の左上から再起動をしますと、なんと画面共有を維持した状態で、そのまま戻ってくれます。これが実に快適です。</p>



<h4 class="wp-block-heading">３　フルスクリーンの分離はマウスで上端を押し上げる</h4>



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



<p>作業性の関係で、この共有画面を分離して、一つのウインドウで表示したい場合があります。その場合に、ちょっとコツが要ります。まず、マウスで画面の上端を持ち上げるようにするとバーが出てきます。そのバーの左にある緑のボタンを押すと、フルスクリーンの解除ができます。</p>



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



<p>MacからMacをコントロールするのが、やはり一番相性がいいですね。</p>



<p>以上</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">24259</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>【STREAM DECK】目的別に作業をしながら〜ブラウザを切り替えて安全に使う</title>
		<link>https://imakat.com/2022/05/01/14886/</link>
		
		<dc:creator><![CDATA[imakat]]></dc:creator>
		<pubDate>Sun, 01 May 2022 01:51:16 +0000</pubDate>
				<category><![CDATA[デジタル]]></category>
		<category><![CDATA[テプラ]]></category>
		<category><![CDATA[SynologyNAS]]></category>
		<category><![CDATA[STREAM DECK]]></category>
		<category><![CDATA[Googleアカウント]]></category>
		<category><![CDATA[高齢者アクセシビリティ]]></category>
		<category><![CDATA[AppleScript]]></category>
		<guid isPermaLink="false">https://imakat.com/?p=14886</guid>

					<description><![CDATA[2022.12.24追記：Macの新OS,Venturaに更新しました。Elgato Stream Deck.appを再インストールしたら、一部、動作しない、ボタンのアイコンが変えられた、という状況になり手作業で修復して [&#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>2022.12.24追記：Macの新OS,Venturaに更新しました。Elgato Stream Deck.appを再インストールしたら、一部、動作しない、ボタンのアイコンが変えられた、という状況になり手作業で修復しています。これに伴う項目の追加 <a rel="noreferrer noopener" href="#422" target="_blank">&lt;４&gt;-２）-２</a>。</p>



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



<p></p>



<p>＜STREAM DECKで目的別に作業を集約する＞<br><span class="fz-12px"><a href="https://imakat.com/page-220501/" target="_blank">別ページで表示</a></span></p>



<img decoding="async" src="https://docs.google.com/drawings/d/e/2PACX-1vSxTB34N8noebSc-TCNfzSEDyDcAU9uwHo-vZS_-y9LSt1Z-xScoTptqaqH-fvOx2k2QDoLTyCqxIq8/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>それから高齢になってくると、アクセルとブレーキを踏み間違えるような、重大な判断ミスを起こすリスクが高くなります。</p>



<p>よく言う知恵は「書いて貼っておけ！」。</p>



<p>最近、テプラをよく使うようになりました。</p>



<p>そこへ重なってくるのがIT化の波ですね。</p>



<p>今回は、YouTubeなどで紹介多数、映像や音楽クリエイターの中では大人気の「STREAM DECK」という製品なのですが、これは、まさに<strong>「テプラ」と「IT」の合体です。</strong>「<strong>高齢者のアクセシビリティの向上</strong>」という観点からも役に立つと思えるので、取り上げてみます。</p>



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



<h4 class="wp-block-heading">＜1＞ ざっくり、STREAM DECKはどのように便利か</h4>



<p>パソコンで作業をするとき、何らかの操作を選択するのですが、普通は二つの方法があります。一つはアプリの上段か下段にあるメニューバーから「コピー」や「ペースト」を選ぶ、あと一つはキーボードのショートカット「⌘+C」、「⌘+V」を押す、です。ショートカットは慣れると何も意識せず手が動くようになるとはいえ、やはり「<strong>ボタンを押すだけ</strong>」の方が早いと思います。</p>



<p>あまり機会はないと思いますが、例えば、決まった箇所のセルを選択する→数字を入れる→結果のセルへ行く→結果をコピーする→別の箇所へペーストする。この作業を1000回やるとしたら、４つの動作をボタンに設定できたら便利です。</p>



<p>それではCOMさんの紹介ビデオをご覧ください。</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="STREAM DECKが便利すぎて全パソコンユーザーにオススメ【elgato | PC周辺機器】" width="1256" height="707" src="https://www.youtube.com/embed/LxUCKS618Xo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>COMさんのビデオは、この製品の機能の魅力に焦点を当てた紹介になっています。他の方には、Zoomを使う、配信する、動画制作、音楽制作、といったある種の作業のカタマリをこの盤面に載せる方法を紹介するビデオになっているものも多いです。</p>



<p>私の紹介も「なるほど」と思ってもらえれば嬉しいです。</p>



<h4 class="wp-block-heading">＜２＞ヤドカリ型業務の置き場所として</h4>



<p>今回私は、業務の塊の一つとして自治会業務を持ってきましたが、PTA、サークル活動、組合、NPOなど何でも同じことです。それで、そうした組織活動において三役・部長など役職になる場合は、任期末に後任に役職の仕事を引き渡すことになります。殆どの組織は小さく、事務員も事務所もありませんので、紙ファイルをドンと手渡しです。この紙ファイルをドンと手渡しされる→作業をする→紙ファイルをドンと次の人へ手渡しする、この基本の流れは変わりませんが。しかし、エコ社会実現に向け、「紙ファイル」の部分は、「データそのものは電子化され、必要に応じて印刷したりパソコンに表示したりする」という形に変化が進んでいます。</p>



<p>仕事の多い役職には、組織からノートパソコンを貸与するのが分かりやすいです。しかし仕事が多いと言っても、パソコン１台となると、そのほんの一部を使っている感じ。エコじゃない。。。壊れたらどうする。</p>



<p>そこで出てくるのが、自分のパソコンを使う、「ヤドカリ型」です。</p>



<h4 class="wp-block-heading">＜３＞STREAM DECKを使おうと思った一番の動機〜<span class="bold-red">個人情報を漏らさないようにすること</span></h4>



<p>「ヤドカリ型業務」の発想に、もう一つ着眼を加えます。</p>



<p>以前からMacを使って、細々と、音楽制作、ブログ作成、IT関連、その他の作業を行っていました。そこへここ数年、自治会の仕事がどどっと入ってきました。自治会の仕事もパソコンやインターネットを使うことが多くなっています。</p>



<p>必要な持ち物は、</p>



<p><span class="marker">「<strong>Googleアカウントと、EXCEL、WORD</strong>」</span></p>



<p>これだけなので、殆どのパソコンで動くことになります。</p>



<p>Googleアカウントとパスワードを後任者へ伝えるだけで移行できるのは、革新です。</p>



<p>しかし、<br>個人のパソコンで自治会の作業をすることになると、</p>



<p>個人のGoogleアカウントと自治会のGoogle<strong><span class="marker">アカウントが複数存在</span></strong>することになります。</p>



<p>その場合に<strong><span class="marker">ウッカリミス</span></strong>が起きやすいです。</p>



<p><strong>自治会のGoogleアカウントで開いたChromeでAmazonのサイトを開き、個人のIDとパスワードを入れて個人の物を注文する、ご丁寧に<span class="fz-16px"><span class="fz-20px"><span class="fz-22px">そのIDとパスワードを保存してしまうというミス</span></span></span>。</strong></p>



<p>そのことに気付かないまま、後任者に引き継ぎしてしまうと、後任者は、なりすまして、買い物ができてしまう(まあ、そんな悪い人は少ないと思いますが）。</p>



<p><br>アクセルとブレーキを踏み間違えるようなミス。</p>



<p>ただ、その間違いを犯すのは自分自身、自分自身で防衛する方策はないのか。</p>



<p>そこで思いついたのが、この機器を使うことによって、</p>



<p><strong><span class="marker">目的別にプロファイルを作ること。<br>個人IDとパスワードを入力するWebサイトは、個人のアカウント(Googleアカウント、iCloudなど）でしか開かないようにすること。</span></strong></p>



<p>です。</p>



<p>そうそう。<strong><span class="marker">それと大事なこと。たとえヤドカリ型の使用にしても、自治会など公的な作業のデータは全て、別のフォルダかデバイスに格納するようにしましょう。</span></strong></p>



<p></p>



<h4 class="wp-block-heading"><strong>＜４＞</strong>AppleScriptをSTREAM DECKへ書き込んで、Googleアカウントの切替を行う</h4>



<p>以下ですが、Automatorでappを作り、STREAM DECKでappを「開く」で起動できれば、それで成功ですが、私の場合、Macの「セキュリティーとプライバシー」でのエラーが解消しないので、以下の方法を取りました。</p>



<h5 class="wp-block-heading">＜４＞-１）AppleScriptを使ってChromeのユーザーを切り替える</h5>



<p>Chromeのユーザーは、現在私の場合、下図の１が個人、２が某目的、３が自治会、４が某目的という使い方になっています。</p>



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



<p>AppleScriptについては、「<a rel="noopener" target="_blank" href="https://waarumstudy.blogspot.com/2020/03/mac-google-chrome-desktop-shortcut.html">IPHONEアプリ個人開発とライフハック<span class="fa fa-external-link external-icon anchor-icon"></span></a>」さんの記事の中の、5,段落に書かれたスクリプトを利用させていただきました。スクリプトの1行目&#8221; set userNumber to 1&#8243;の数字を、例えば自治会用であれば&#8221;set userNumber to 3&#8243;にします。</p>



<p></p>



<h5 class="wp-block-heading">＜４＞-２）-１ AppleScriptをSTREAM DECKへ書き込み実行する方法＜その１＞</h5>



<p>AppleScriptを書き込み実行できるようにするプラグインを入手してインストールします。</p>



<p><a rel="noopener" target="_blank" href="https://github.com/mushoo/streamdeck-applescript">ダウンロードサイト<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<p>「Release」をクリックします↓</p>



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



<p>com.mushoo.RunAppleScript.streamDeckPlugin をクリックします↓</p>



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



<p>Downloadをクリックします↓</p>



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



<p>ダウンロードされたファイルをクリックします↓</p>



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



<p>STREAM DECKにRunAppleScriptがインストールされました。これをボタンにドロップします↓</p>



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



<p>AppleScriptを書き込みます↓</p>



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



<div id="422"></div>



<h5 class="wp-block-heading">＜４＞-２）-２ AppleScriptをSTREAM DECKへ書き込み実行する方法＜その２＞</h5>



<p>最初＜その１＞で作成していたのですが、新OS Venturaへ更新したところ、なぜか、RunAppleScriptが消失してしまいました。再インストールを試みましたが、既存であるとのエラーで、先に進みません。そこで、RunAppleScriptに頼らない、元からある方法、つまり素直に、Appleスクリプトエディタを使って記述することにしました。</p>



<p>Stream Deckへ直接記述(インライン)しない方法は、ちょっと面倒にも感じますが、スクリプトファイルが一つのフォルダで管理できるのは便利で、一長一短です。</p>



<p>新たな発見ですが、<strong>アプリケーションファイルappに変換しなくても、スクリプトファイルscptのままで、それをStream Deckのボタンの場所へドラッグ＆ドロップするだけで動作しました</strong>。以下のような流れです。</p>



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



<p></p>



<h4 class="wp-block-heading">＜5＞ディレクトリ名（フォルダ名、ファイル名）は日本語を使わないこと！</h4>



<p>ちょっと脱線して、NAS上のフォルダを呼び出す場合の注意点を書きます。写真動画の取り込みの流れは、私の例では、下図のようになっています。DropboxとSynologyNASはどちらか一つでいいではないか、そうも言えますが、心配し過ぎかも知れませんが、自宅のSynologyNASがもし災害で破損した時のバックアップの考えです。クラウドサービスの中ではDropboxだけの問題かも知れませんが、スマホから写真動画をアップロードするフォルダ名は日本語で「カメラアップロード」と決まっています。このSTREAM DECKのAppleScriptの記述では、ディレクトリ名に日本語が使えません。そこで、SynologyNAS側の同期フォルダ名を「camera_up」と英小文字にしました。</p>



<p></p>



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



<p>AppleScriptの記述は以下になります。</p>



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



<p>AppleScriptは、</p>



<pre class="wp-block-code"><code>tell app "Finder" to open location "smb://<strong><span class="bold-red">aaaaaaa</span></strong>:<span class="bold-red">bbbbbbb</span>@<span class="bold-red">ccccc.ccccc.ccc</span>/<span class="bold-red">ddddd</span>"</code></pre>



<p><strong><span class="bold-red">aaaaaaa</span></strong>は、サーバーアドレスで、SynologyNASの場合、コントロールパネル-&gt;ファイルサービス-&gt;SMBのところに書かれています。</p>



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



<p><span class="bold-red">bbbbbbb</span>は、SynologyNASにMacから接続するときのパスワードです。<span class="bold-red">ccccc.ccccc.ccc</span>は、IPアドレスまたはホスト名、<span class="bold-red">ddddd</span>は、ディレクトリ名です。</p>



<p>なおRunAppleScriptが動作しない場合は、<a href="#422" target="_blank" rel="noreferrer noopener">こちらへ</a>。</p>



<p>それでは、「自治会作業」のプロファイルへ戻って。。。</p>



<h4 class="wp-block-heading">＜６＞出来上がったプロファイルの例</h4>



<p>「自治会作業」プロファイルの例です。関係するアプリやフォルダを一まとめにしています。Webアプリは全て自治会アカウントGoogle内で完結します。</p>



<p>多少脚色もありますが説明します。<br>「自治会作業」：プロファイル切替用ボタン<br>「自治会アカウントGoogle」：自治会アカウントのGoogle Chromeが立ち上がります。<br>「R4自治会」〜「自治会ドライブ」：各種フォルダ<br>「Googleスプレッドシート」〜「Google図形描画」：Googleのアプリです。自治会アカウントで立ち上がります。<br>「Microsoft Excel」〜「Microsoft Word」：そのものです。<br>「メール」：そのものです。<br>「スクショ」：スクリーンショットのショートカット「⌘+↑+4」。<br>「スキャン」：EpsonのScanSnapのアプリ。<br>「Chromeリモート」：自治会アカウントのChromeリモートが立ち上がります。<br>「会員名簿」「AppSheetの作成」：自治会アカウントGoogleで動くAppSheetアプリです。<br>「お知らせ投稿」：自治会アカウントGoogleで動くBloggerです。<br>「自治会ネット掲示板」：自治会アカウントGoogleで動くGoogleサイトです。<br>「公民館カレンダー」：自治会アカウントGoogleで動くGoogleカレンダーです。</p>



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



<p>「ブラウジング」のプロファイルは以下です。個人アカウントのGoogle Chromeが立ち上がります。「YouTube」「Amazon」などボタンがありますが、ちょっと面倒ですが、<strong>全部、マルチアクションを使っています</strong>。別のプロファイルへコピーしても個人アカウントから起動させるためです。「RunAppleScript」で個人アカウントへ切り替える→「Stream Deck:遅延」→「システム：Webサイト（例えばAmazonのURL)」の順です。YouTubeも個人アカウントで開きますので履歴は個人アカウントにだけ残ります。<strong>自治会アカウントのYouTube履歴に残るようなことはありません</strong>。</p>



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



<p></p>



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



<p>この一連の登録作業ですが、高齢者にとってはまだまだ難しいです。しかしながら、登録さえしてしまえば、あとはワンタッチ。まさに「<strong>高齢者のアクセシビリティの向上</strong>」に貢献する製品です。ここでは触れませんでしたがIFTTTプラグインを入れれば家電製品をコントロールをできるようになります。この製品により、高齢者、障害者にとって役立つ様々な活用が広がりそうな感じがしますが、残念なのは、32ボタンのもので約3万円と高く、私のようなマニアックな人向けの価格帯です。1万円を切れば、かなり広がる気がします。</p>



<p>以上</p>



<iframe sandbox="allow-popups allow-scripts allow-modals allow-forms allow-same-origin" style="width:120px;height:240px;" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" src="//rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=imakat-22&#038;language=ja_JP&#038;o=9&#038;p=8&#038;l=as4&#038;m=amazon&#038;f=ifr&#038;ref=as_ss_li_til&#038;asins=B07RL8H55Z&#038;linkId=5119bb1b6427d4956cc190904692ee25"></iframe>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">14886</post-id>	</item>
	</channel>
</rss>
