html・Javascriptでwebカメラを使用する方法

<h1>Webカメラの映像表示</h1>
	<div>
		<video id="video" width="600px" height="400px"></video>
	</div>
	<script>
		const video = document.getElementById("video")
		navigator.mediaDevices.getUserMedia({
			video: true,
			audio: false,
		}).then(stream => {
			video.srcObject = stream;
			video.play()
		}).catch(e => {
			console.log(e)
		})
	</script>

このファイルが次の許可を求めていますと表示される。

OK これでjsのopenCVを使いたい

[Amazon Kinesis Video Stream] VideoJSでHTML側で取得して表示

KVSのHLSStreamingSessionURLを取得してvideojsでストリーミング表示する

credentials.js

const AWS_ACCESS_KEY_ID = '';
const AWS_SECRET_ACCESS_KEY = '';
const AWS_REGION = 'ap-northeast-1';
const AWS_STREAM_NAME = 'MyKinesisVideoStream';

html

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link href="https://vjs.zencdn.net/7.15.4/video-js.css" rel="stylesheet" />
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.642.0.min.js"></script>
    <script src="credentials.js"></script>
</head>
<body>
    <video id="videojs" class="player video-js vjs-default-skin" data-setup='{"fluid":true}' controls autoplay muted></video>

    <script src="https://vjs.zencdn.net/7.15.4/video.min.js"></script>
    <script>
        window.addEventListener("unhandledrejection", function(event){
            console.warn("WARNING: Unhandled promise rejection." + event.reason);
            location.reload()
        });
        window.onerror = (message, file, lineNo, colNo, error) => {
            console.error('window.onerror', message, file, lineNo, colNo, error);
            location.reload()
        }

        async function getURL(){
            const accessKeyId = AWS_ACCESS_KEY_ID;
            const secretAccessKey = AWS_SECRET_ACCESS_KEY;
            const region = AWS_REGION;
            const streamName = AWS_STREAM_NAME;

            const options = {
                accessKeyId: accessKeyId,
                secretAccessKey: secretAccessKey,
                region: region,
            }
            const kinesisVideoClient = new AWS.KinesisVideo(options);
            const kinesisVideoArchivedMediaClient = new AWS.KinesisVideoArchivedMedia(options);

            const e = await kinesisVideoClient.getDataEndpoint({
                APIName: 'GET_HLS_STREAMING_SESSION_URL',
                StreamName: streamName
            }).promise();
            kinesisVideoArchivedMediaClient.endpoint = new AWS.Endpoint(e.DataEndpoint);

            const d = await kinesisVideoArchivedMediaClient.getHLSStreamingSessionURL({
                DisplayFragmentTimestamp: 'ALWAYS',
                StreamName: streamName
            }).promise();
            return d.HLSStreamingSessionURL;
        }

        document.addEventListener('DOMContentLoaded', async() => {
            const url = await getURL();
            const player = videojs('videojs');
            player.src({
                src: url,
                type: 'application/x-mpegURL'
            });
            player.on('error', function(){
                console.log(player.error());
                location.reload();
            });
            setInterval(() => {
                const t = player.currentTime();
                console.log("current Time is "+ t +" seconds");
            }, 5000)
        });
    </script>
</body>
</html>

### mac
kvsのsdkをdownloadした状態とする
https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp.git

macのカメラからKVSに映像を送る
$ gst-launch-1.0 avfvideosrc device-index=0 ! videoconvert ! video/x-raw,format=I420,width=1280,height=720 ! vtenc_h264_hw allow-frame-reordering=FALSE realtime=TRUE max-keyframe-interval=45 bitrate=512 ! h264parse ! video/x-h264,stream-format=avc,alignment=au,profile=baseline ! kvssink stream-name=MyKinesisVideoStream storage-size=512 access-key=”${access-key}” secret-key=”${secret-key}” aws-region=”ap-northeast-1″

$ php -S 192.168.34.10:8000
http://192.168.34.10:8000/

ちょっと待ってくれ
なんか凄い事やってる様な気がする…🥺

[Lazy Load] 画像の遅延ロードの書き方

class=”lazyload”とし、画像はdata-srcで読み込む。
lazyloadはcdnで読み込み、scriptでlazyload();とする。

	<img class="lazyload" data-src="img/1.jpg" width="300" height="200"><br><br><br><br>
	<img class="lazyload" data-src="img/2.jpg" width="300" height="200"><br><br><br><br>
	<img class="lazyload" data-src="img/3.jpg" width="300" height="200">
	<script src="https://cdn.jsdelivr.net/npm/lazyload@2.0.0-rc.2/lazyload.min.js"></script>
	<script>
    lazyload();
	</script>

Googleのdevtoolで確認すると、3枚あるのが2枚しか読み込まれていないことがわかる。

なかなかやりおる

[JavaScript] Classの追加(add)を操作する

タブメニューで、URLのパスに応じてメニューのis-activeをつけたい時
L ulのli要素にclassで”is-active”をつけたい
html

<div class="tabs">
      	<ul id="mylist">
      		<li><a href="/btc">BTC</a></li>
      		<li><a href="/eth">ETH</a></li>
      		<li><a href="/xrp">EXP</a></li>
      		<li><a href="/xlm">XLM</a></li>
      		<li><a href="/mona">MONA</a></li>
      	</ul>
      </div>

javascript側
L location.pathnameでURLを取得する
  L querySelectorAllでli要素を全て取得する
  L classList.addでclassを付与する

const pathname = location.pathname;
  	var i;
  	switch(pathname){
  		case '/btc':
  			i = 0;break;
  		case '/eth':
  			i = 1;break;
  		case '/xrp':
  			i = 2;break;
  		case '/xlm':
  			i = 3;break;
  		case '/mona':
  			i = 4;break;
  	}
  	var cols = document.querySelectorAll('#mylist li');
  	cols[i].classList.add('is-active');

OK
やりたいことの7割くらいまでは出来た

fetchAPI

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- <link rel="stylesheet" type="text/css" href="styles.css"> -->
</head>
<body>
  <select id="sel">
      <option> --場所を選ぶ-- </option>
      <option value="kyoto">京都</option>
      <option value="osaka">大阪</option>
      <option value="kobe">神戸</option>
  </select>

  <div id="mes">
    集合場所は<span id="pos"></span>
    集合時刻は<span id="time"></span>
  </div>
    <script>
      const url = "ajax_getData.php";
      let selid = document.getElementById('sel');

      selid.addEventListener('change', function(){
        let optval = selid.options[selid.selectedIndex].value;
        let param = new URLSearchParams();
        param.append("opt",optval);

        fetch(url, {
          method: "post",
          body: param,
        }).then(response => {
            if(response.ok){
              let promise = response.json();
              promise.then(data =>{
                document.getElementById('pos').innerHTML = data.position;
                document.getElementById('time').innerHTML = data.ap_time;
              })
            } else {
              alert("request failed");
            }
        })
      })
    </script>
</body>
</html>

なるほど。。。
ajaxの取得をtime intervalで数秒ごとに取るようにして表示すれば良いのか。
ほぼほぼロジックも出来たので背景処理のところだな

[JavaScript]aタグでテキストエリアの内容をコピー

Output(翻訳結果)をボタン一つでコピーしたい。
L aタグでjsの関数を実行させる
  L getElementsByTagName(“textarea”)[0]でtextareaのtextを取得し、*.select でコピーします。

<div class="card-footer ">
                {!! Form::label('dest', '英語(翻訳結果)') !!}
                {!! Form::textarea('dest', $output, ['class' => 'form-control' ]) !!}
                <a href="javascript:OnLinkClick();">コピー</a>
              </div>

<script>
function OnLinkClick(){
    var text = document.getElementsByTagName("textarea")[1];
    text.select();
}
</script>

おおおおおおおおおおおおお
ええやんか

別ウィンドウでブラウザを開閉するaタグ・JSの書き方

アプリケーションで一部の機能を別ウィンドウで表示させ、ウィンドウを閉じるリンクも設置させたい時

### 別ウィンドウのリンク
– aタグに直接window.openとして書きます。ここではwidth500 height400のウィンドウです。

<a href="./translate.html" onclick="window.open('./translate.html', '', 'width=500,height=400'); return false;">翻訳</a>

### ウィンドウを閉じる
– window.closeで閉じます。

<a class="nav-link btn-magnify" href="" id="close">ブラウザを閉じる</a>

// 省略

<script>
    let close = document.getElementById('close');
    close.addEventListener('click', ()=>{
      window.close();
    });
  </script>

中々良い感じです。

国ごとの電話コードのJavaScriptライブラリ「International Telephone Input」を使う

国際電話の電話コードの入力の助けになる様なJSライブラリがないか探した
例えば、日本の場合は国際電話の場合 「+81 -*」となる
どうやら、jQueryでInternational Telephoneというのがあるらしい
https://github.com/jackocnr/intl-tel-input

GithubからzipファイルをDLして、build側のフォルダからintlTelInput.css と intlTelInput.jsを使います。
src側のフォルダからintlTelInput.jsを使うと、「window.intlTelInput is not a function」とエラーになるので注意が必要

<link rel="stylesheet" href="css/intlTelInput.css">
// 省略
                <div class="form-group">
                  <label for="tel">電話番号</label>
                  <input type="tel" name="tel" id="mobile-number" class="form-control col-md-6">
                </div>
// 省略
  <script src="js/jquery.min.js"></script>
  <script src="js/intlTelInput.js"></script>
  <script>
  var $input = document.querySelector("#mobile-number");
  window.intlTelInput($input, {
      defaultCountry: "us",
    });
  </script>

OK、顧客登録側はほぼほぼ出来たかな^^

海外のzipcode からAPI で住所を取得する

zipcodebaseというサイトを使ってみます。
こちらのサイトでregisterしてapi keyを取得します。
https://zipcodebase.com/

– ブラウザで試す
https://app.zipcodebase.com/api/v1/search?apikey=${api_key}&codes=1000001

-> response
{“query”:{“codes”:[“1000001″],”country”:null},”results”:{“1000001”:[{“postal_code”:”100-0001″,”country_code”:”JP”,”latitude”:”35.67490000″,”longitude”:”139.76190000″,”city”:”Chiyoda”,”state”:”Tokyo To”,”city_en”:”Chiyoda”,”state_en”:”Tokyo To”,”state_code”:”40″,”province”:”Chiyoda Ku”,”province_code”:”1864529″},{“postal_code”:”1000-001″,”country_code”:”PT”,”latitude”:”38.71670000″,”longitude”:”-9.13330000″,”city”:”Lisboa”,”state”:”Lisboa”,”city_en”:”Lisboa”,”state_en”:”Lisboa”,”state_code”:”14″,”province”:”Lisboa”,”province_code”:”1106″}]}}

– formでやってみる

	<form action="https://app.zipcodebase.com/api/v1/search" method="post">
	  <input type="text" name="codes">
	  <input type="hidden" name="apikey" value="${api-key}">
       <input type="submit" value="送信">
</form>

-> エラーになります。

– PHPで書きます。

$ch = curl_init();

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);

$data = [
	"codes" => "1000001",
];

curl_setopt($ch, CURLOPT_URL, "https://app.zipcodebase.com/api/v1/search?". http_build_query($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
		"Content-Type: application/json",
    	"apikey: ${api_key}",  
));

$response = curl_exec($ch);
curl_close($ch);

$json = json_decode($response);

print("<pre>");
var_dump($json);
print("</pre>");

### フォームでzip codeを送信して結果を表示する様に書きたい
– get methodで値があればcurlする様に書く

$postcode = $_GET['postcode'];
if($postcode != null) {
	echo $postcode;
}

– htmlのformと合わせて書きます。

$postcode = $_GET['postcode'];
if($postcode != null) {
	$postcode = str_replace('#', '', $postcode);
	$ch = curl_init();

	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HEADER, false);

	$data = [
		"codes" => $postcode,
	];

	curl_setopt($ch, CURLOPT_URL, "https://app.zipcodebase.com/api/v1/search?". http_build_query($data));
	curl_setopt($ch, CURLOPT_HTTPHEADER, array(
			"Content-Type: application/json",
	    	"apikey: ${api-key}",  
	));

	$response = curl_exec($ch);
	curl_close($ch);

	$json = json_decode($response);

	// echo $json['result'][$postcode][0]['city'];
	$city = $json->results->$postcode[0]->city;
	$state = $json->results->$postcode[0]->state;
	$country_code = $json->results->$postcode[0]->country_code;

}


?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>
<body>
	<h1>Worldwide PostCode Search</h1>
	<form action="/" method="GET">
	  <input type="text" name="postcode" placeholder="ハイフン抜きで入力してください">
       <input type="submit" value="送信">
</form>
<br><br>
<?php
	if($city != null){
		echo "<h3>「" . $postcode . "」のZipcode情報です!". "</h3>";
		echo "Country:" .$country_code . "<br>";
		echo "State:" .$state . "<br>";
		echo "City:" .$city . "<br>";
	}
?>

Coountry, state, cityを取れます。
$responseをvar_dumpすることで、jsonでどの項目が取得できるか確認できます。

$json = json_decode($response);
var_dump($json);

ライブラリやツールも否応なしに海外の物を使うから勉強になります。
リンクを追加

[JS] Real Time User:現在●人が見ていますを表示

ページで、現在●人が見ていますを表示したい

<p>現在: <div class="realtimeuserscounter"></div>人が見ています。</p>
<script src="https://realtimeusers.bycontrast.co/realtimeusers.js"></script>

デフォルトだとPowered なんちゃらが表示されて、改行されるので、display inlineとdisplay noneで少し修正します。

	<p style="display:inline;">現在: <div class="realtimeuserscounter" style="display:inline!important;"></div>人が見ています。</p>
<script src="https://realtimeusers.bycontrast.co/realtimeusers.js"></script>
<script>
var num = document.getElementsByClassName('realtimeuserscounter__num');
for(var i = 0; i < num.length; i++) {
num[i].style.display = "inline";
}
var kesu = document.getElementsByClassName('realtimeuserscounter__attr');
for(var i = 0; i < kesu.length; i++) {
kesu[i].style.display = "none";
}
</script>

これ、変えていいのかな?
サイト見たけどようわからん。。。