今日のプログラマ

AFN 360の配信URL一覧の取得

AFN 360 Inertnet Radioは2020年末にPLSファイルの取得が不安定になり年明けにほぼ接続できなくなりました。
代わりにXMLによる配信URL一覧があります。

横田エアベースのXML例:https://playerservices.streamtheworld.com/api/livestream?station=AFNP_TKO&transports=http,hls&version=1.8
※上記リンクをFirefox開く場合はXMLを表示する拡張機能が必要です。

このXMLの中にはコーデックがmp3とAACによる配信URLが、それぞれ複数提示さてています。
この複数の配信URLからアトランダムに選択(負荷分散)して接続する仕組みです。

AFNP_TKOの部分の一覧
Tokyo=AFNP_TKO
Sasebo=AFNP_SBO
Okinawa=AFNP_OKN
Misawa=AFNP_MSW
Iwakuni=AFNP_IWA
Casey=AFNP_CSY
Kunsan=AFNP_KSN
Osan=AFNP_OSN
Yongsan=AFNP_YSN
Daegu=AFNP_DGU
Country=AFN_CTYP
Freedom=AFN_FREP
Fans=AFN_FAN
Gravity=AFN_GRV
Hot AC=AFN_HOTP
Joe Radio=AFN_JOEP
Legacy=AFN_LGYP
PowerTalk=AFN_PTK
The Voice=AFN_VCE

ちゅんラヂはAFNの配信URLをXMLから取得している
AFNの配信URLは結構な頻度で変更されます。ちゅんラヂはその都度、配信URLのプリセットを変更していました。
そこでXMLの配信一覧から、配信URLを取得する方法に変更しました。これで配信URLが変わっても安心です。XML自体のURLと書式が変更されたらダメですけど。

下記JavaScriptのソースコードがAFNの配信URLを取得する事例です。
ソースコード中の「xml2json.js」は先人の知恵を利用させて頂いております。
XHRでXMLのDOM Treeがそのまま戻せるのに、responseXMLをなぜ使うんだ?
いまさらPromiseの中でXHRは無いだろ、fetch使えよ!
などというツッコミどころがありますが大目にみてやってください。使うならもっとモダンに書き換えてください。
もっと具体的にどの様に使われているのかを知りたい場合はちゅんラヂPlayerのソースコードをリバースエンジニアリングしてください。

JavaScriptが読めなくても、上記XMLリンク先の横田エアベースのXML内容をじっくり見ると、何しているかが推測できると思います。

function getAfnURL(afnID) 
	return new Promise((resolve, reject) => 
		let xhr = new XMLHttpRequest();
		xhr.open('GET',`https://playerservices.streamtheworld.com/api/livestream?station=${afnID}&transports=http,hls&version=1.8`, true);
		xhr.onload = function() 
			if (xhr.readyState === xhr.DONE && xhr.status === 200) 
				//読み込んだXMLをObjectとしてメモリーに展開
				let plsDom = xhr.responseXML;			//読み込んだxml DOM
				let plsStr = xml2json(plsDom,'');		//XML DOMをJSON Stringに
				let pls = JSON.parse(plsStr);			//JSON StringをOjectに
				let mp3Urls = [];		//複数のmp3配信URLを取得する配列
				let aacUrls = [];		//複数のaac配信URLを取得する配列
				//配信リストを取得
				let mountPoints = pls.live_stream_config.mountpoints;
				mountPoints.mountpoint.forEach((mountPoint) => 
					mountPoint.servers.server.forEach((server) => 
						let codec = mountPoint["media-format"]["audio"]["@codec"];
						if (codec == "mp3") 
							//mp3配信URL ※mountSuffixは配信方式リストから有効な方式を判定するのが正しいらしいが、AFNはshoutcast-v1らしいので、固定指定
							mp3Urls.push(`https://${server.ip}/${mountPoint.mount}_SC`);	//配信URLを編集してpush
						} else 
							//HE-AACv2配信URL ※mountSuffixは配信方式リストから有効な方式を判定するのが正しいらしいが、AFNはshoutcast-v1らしいので、固定指定
							aacUrls.push(`https://${server.ip}/${mountPoint.mount}_SC`);	//配信URLを編集してpush
						}
					})
				});
				//複数ある配信ストリーミングURLリストからアットランダムに選定 ※mp3優先
				let ix = 0;
				if (mp3Urls.length > 0) 
					//mp3のストリーミング
					ix = Math.floor( Math.random() * (mp3Urls.length - 1) );
					resolve(mp3Urls[ix]);
				} else 
					if (aacUrls.length > 0) 
						//aacのストリーミング
						ix = Math.floor( Math.random() * (aacUrls.length - 1) );
						resolve(aacUrls[ix]);
					} else 
						console.log('[radio._getAfnUrl] error: Streaming URL is empty');
						reject(new DOMException('AFN streaming URL is empty ERROR', 'OperationError'));
					}
				}
			} else 
				console.log('[radio._getAfnUrl] error: Could not get xml normally');
				reject(new DOMException('AFN playlist XML read ERROR', 'OperationError'));
			}
		};
		xhr.onerror = function() 
			console.log('[radio._getAfnUrl] error:' + new Error(xhr.statusText));
			reject(new DOMException('AFN playlist loading XHR ERROR', 'OperationError'));
		};
		xhr.send();
	});
}
※Promise部分について
この事例はAFNのサーバーからXML取得の応答を待ちますので非同期関数にしています。
JavaScript以外でもモダンな言語ならPromise(またはFuture)が実装されていますので同様です。

| | コメント (0)

長らくFirefoxでちゅんラヂの動作が不調

2021-04現在、下記の事象は改善されています。

ここに記する問題はChromium系のブラウザなら何の問題も無く動作しますので、ちゅんラヂはそれらのブラウザで利用してください。

ちゅんラヂがFirefoxクラッシャーになっている問題は2点あります。

Web Audio APIのガベージコレクションが駄目で、タブ毎にサンドボックス化されておらず、他のタブにも影響する現象があり、これアプリ側ではなんともできません。この現象はFirefoxを再立ち上げするか、about:memoryでメモリーを開放させれば復帰します。

もう一つ、radikoを外部リンクをwindow.openで開く時に、糞詰まり(下品な表現ですみません)してwindowが開かない現象に遭遇しています。デバックでwindow.openのところでブレークして、ステップインでwindow.openを実行、そのタイミングでCtrl+Shift+Rでリロードすると、糞詰まりでしているwindowが開きます。この現象もタブを超えて伝播する不具合です。

もう何がなんだかわけりません。FirefoxもChromeと同じ様に複数のプロセスを起動して他のタブに影響しないようになったんじゃないのかと思ってたのですが、どうやらそうでもないらしい。

こんな事があってもFirefoxはメインで利用しているブラウザです。
この2つの現象が改善されることを願い、フィードバックはあげてあります。

| | コメント (0)

Google翻訳を翻訳頻度が高い三択の言語で開く

PC版のGoogle翻訳は日本においては英語・日本語・韓国語の三択が開きます。
これを、できれば翻訳頻度が高い三カ国語の三択で開きたい。

そこで

フランス語・英語・日本語の組み合わせで開くURLです。
https://translate.google.com/?hl=ja&sl=fr&tl=fr#view=home&op=translate&sl=en&tl=ja

スペイン語・英語・日本語の組み合わせで開くURLです。
https://translate.google.com/?hl=ja&sl=es&tl=es#view=home&op=translate&sl=en&tl=ja

この様によく使う三択を組み合わせたURLをブックマークしておけば、毎回、三択を切り替えるストレスが減ります。

上記に辿り着くまでに、URL引数を色々と試したのですが完全には解りませんでした。
しかし日本語と英語は固定で、もう一カ国語を好きな言語にするという三択ならうまく行きました。

URL引数の意味は多分下記の通り?

hl=ja     翻訳ページを日本語で表示する
sl=fr&tl=fr  三択の中の一つをフランス語にする *1
#view=home&op=translate ?わかりません
sl=en&tl=ja  開いた時の翻訳方向は英語から日本語

*1 三択の中の一カ国を指定する部分の記号は下記のとおりです。

Afrikaans    Afrikaans        af
Albanian    Shqip          sq
Arabic     عربي          ar
Armenian    Հայերէն        hy
Azerbaijani   آذربایجان دیلی     az
Basque     Euskara         eu
Belarusian   Беларуская  be
Bulgarian    Български   bg
Catalan     Català         ca
Chinese (Simp.) 中文简体        zh-CN
Chinese (Trad.) 中文繁體        zh-TW
Croatian    Hrvatski        hr
Czech      Čeština         cs
Danish     Dansk          da
Dutch      Nederlands       nl
English     English         en
Estonian    Eesti keel       et
Filipino    Filipino        tl
Finnish     Suomi          fi
French     Français        fr
Galician    Galego         gl
Georgian    ქართული       ka
German     Deutsch         de
Greek      Ελληνικά     el
Haitian Creole Kreyòl ayisyen     ht
Hebrew     עברית        iw
Hindi      हिन्दी        hi
Hungarian    Magyar         hu
Icelandic    Íslenska        is
Indonesian   Bahasa Indonesia    id
Irish      Gaeilge         ga
Italian     Italiano        it
Japanese    日本語         ja
Korean     한국어         ko
Latvian     Latviešu        lv
Lithuanian   Lietuvių kalba     lt
Macedonian   Македонски  mk
Malay      Malay          ms
Maltese     Malti          mt
Norwegian    Norsk          no
Persian     فارسی         fa
Polish     Polski         pl
Portuguese   Português        pt
Romanian    Română         ro
Russian     Русский     ru
Serbian     Српски      sr
Slovak     Slovenčina       sk
Slovenian    Slovensko        sl
Spanish     Español         es
Swahili     Kiswahili        sw
Swedish     Svenska         sv
Thai      ไทย           th
Turkish     Türkçe         tr
Ukrainian    Українська   uk
Urdu      اردو          ur
Vietnamese   Tiếng Việt       vi
Welsh      Cymraeg         cy
Yiddish     ייִדיש        yi

| | コメント (1)

ちゅんラヂのビジュアライザー

ラジオは聞くもので見るものじゃないですが、ふとプレイヤーに目をやった時に動きがほしい。ちゅんラヂのビジュアライザはそんな経緯で実装したものです。

それで判ったことは、放送局によって高音の伸びに差がある事です。
同じJCBAからの配信でも局によって高音の伸びが違います。かなり差があります。
過入力でクリッピングしている放送局は高音の音圧が大きく歪みが発生しているのが判ります。
面白いのは、アナウンスの声とは連動していない信号が、モスキート域にかなり強いレベルで入っている番組がありました。これって若者向けに何らなのメッセージを埋め込んでいるのかなと勘ぐりたくなるものでした。残念ながら私の耳では確認しようがありません。

本題のビジュアライザーの実装方法です。
原作は「Web Audio APIを使ってDAW(っぽいもの)を作ってみる」で、それをフォークしてちゅんラヂ用に機能を調整しました。有難うございます。ビジュアライザーの技術的な理解はそちらをご覧ください。

ここでは、機能調整した内容だけを書き留めておきます。

■フォークしして機能調整したソースコード
 http://7design.jp/js/tunein2vis.js
 ソースコード中にコメント記述してありますので解説は省略します。

■機能調整したこと
・描画色をちゅんラヂ用に青系に変更
・stop機能を追加 ※ちゅんラヂで一時停止や再選局した時に描画ループを止める為
・周波数目盛表示のレスポンシブ対応
・スペアナ描画と周波数目盛のズレを改善 ※描画周波数の求め方を改善
  確認事例 http://7design.jp/tunein2radio.html?area=NET13
・正弦波のスペアナ表示で歯抜け欠落する事があったので改善
・音量バーを表示
・Web Audio APIじゃない時は独自アニメイメージと音量バー情報のみを描画
・スペアナの描画を20Khzまでに限定 ※ちゅんラヂは20Khz以上が不要な為

■機能追加したメソッド
・stop() 描画ループを止める ※Web Audio APIのリソース開放前に利用
・setInfo() 右下に情報表示させる情報を受ける ※ちゅんラヂでは音量表示で利用
・setVolue() 音量バーの値を受ける

■実装事例
・ビジュアライザー組み込み完成形【ちゅんラヂ】
http://7design.jp/tunein2radio.html    スペアナ表示
http://7design.jp/tunein2radio.html?wave  波形表示
・利用しているイメージファイルは以下のフォルダからご自由に取得してください
https://www.7design.jp/img/
・ブログへのちゅんラヂプレイヤー埋込事例
http://nakkara.cocolog-nifty.com/nakkara/cat24152847/index.html

| | コメント (0)

MS Edge(EdgeHTML版)の“event”オブジェクトとは何者?

ちゅんラヂがMS Edge(EdgeHTML版)で動かなくなっていました。原因は機能変更で「event」という変数名を使った為でした。
EdgeHTML版だけの現象です。BlinkエンジンをつかっているAndroid版EdgeとPC向け開発中のEdgeでは問題ありません。
そのうちにEdgeHTML版はBlink版に置き換えられるので放置しようという考えも少し過りました。
しかし、この件は“event”などという、如何にもシステム内部で使われていそうな名称を使った自分に反省!!。ということで名称を“eventUI”に変更しました。因みに“event”はJavaScriptの予約語ではありません。

 

上記の修正をしたのですがEdgeHTML版ではまともに動きませんでした。エラーはでませんが幾つかの不具合があります。
・ブロック要素を透過で重ねた時にCSS指定より上に表示される
 └→複雑にブロックを重ねるた時の解釈で描画が崩れる
・ビジュアライザー表示が出来ない
 └→analyserのgetByteFrequencyDataの値取値がZeroしか帰ってこない
・audioのplay()をPromiseで同期処理させるとエラーが帰る
 └→audioがPromise体操していない?Safariと同様に( ..)φメモメモ
EdgeHTML版Edgeはモダンブラウザとして扱っちゃダメみたいですね。Polyfillを使ってもWeb Audio APIは無理ですし、Edgeは来年の春ごろにBlink版に置き換えられる予定です。そこでEdgeHTML版Edgeへの対応を探るのは止めて放置する事にしました。
Tridentから派生したEdgeHTMLは、2015年にリリースされてから4年を経過しても、Blinkに追いつけて居ないようです。マイクロソフトがEdgeHTMLを捨てる決断をしたのは、もしかしてEdgeHTMLのメンテナンスのギブアップか?

 

■蛇足です■
2020年でFlash Player廃止、Windows Media Serverサポート終了など、Edgeがblinkエンジンに切り替えなどでレガシーな環境の幾つかがウェブの世界から消えます。
その後も残るレガシーはIEです。.NETのActiveXコントロールに依存しているシステムがまだ現役みたいですので、簡単には抹消できないのかもしれません。今となっては、ウェブに対する初期の頃の.NETの功罪はXMLHttpRequestが功で、ActiveXコントロールが罪です。ウェブでのActiveXコントロール利用はEdgeのエンタープライズモード経由(IEモード)のみにマイクロソフトがしてくれれば、IEの廃止ができると思うのです。ぜひともそうして欲しい。ActiveXコントロール以外でIE独自タグを使っていてIEでしかまともに閲覧できいサイトは、もう賞味期限切れという事で良いのじゃないかと思います。

 

日本のブラウザ・ガラパゴスも2020年で脱却してほしいです。IE等のレガシー対応が無くなればウェブ開発者がかなり楽になります。そんな思いもあり、個人の趣味的サイトであるちゅんラヂはIEを拒絶する作りにしてあります。EdgeHTML版Edgeも拒絶しようかな・・・。つでにiOS9以前のSafariも拒絶・・・。

 

あと、サイマルラジオのらじる、Radiko、Listen RadioのIE対応がFlash Player依存です。これらのサイマル ラジオはIEのみの機能では対応できない配信方式ですのでFlash Playerを使っているのです。もしかして2020年には、これらのサイマルラジオがIE対応を止める可能性があるかもしれません。そうなれば個人的にはIE利用者が減少するかもしれませんので歓迎です。
ということで2020年はサイマル ラジオ聴取関係に動きがあるかもしれません。らじるとRadikoはIE対応を止めるのはIE版を放棄するだけ、Listen Radioはモダンブラウザ向けにプレイヤーを新調する必要がありますので、何かをしてくると思われます。

 

■追伸:2019-10■
EdgeHTML版のMS Edgeでのちゅんラヂ動作不具合ですが、Windows 10 Update後に解消された様です。
来年切り替え予定のChromium版はブラウジングだけなら既に安定しています。Edge独自機能はまだ未完成という感じです。ウェブ開発でEdgeHTMLでの動作確認が減るだけでも楽になるので、早く切り替わらないかなと思っています。

| | コメント (0)

Sublime Text と Visual Studio Code

Visual Studio Code(VSCode)を使ってみました。これはHTML+CSS+JavaScritの手打ち派にお勧めのエディッタです。

Sublime Textを利用している人ならVSCodeは違和感なく使えます。そうです画面と操作方法がそっくりなのです。パクリと言えるくらい似ています。真似したマイクロソフトの面目躍如です。
Visual Studioという冠がついていますがオープンソースでNode.js+Electron+TypeScriptで作成されいます。
すこぶる軽快に動作します。Visual Studioのソースエディッタの様にまったりしていません。
最近のマイクロソフトは個人プログラマに優しくなっていたんですね。

JavaScript打ち込みで「this.」と入力すると、その位置でthisが示す選択肢が表示されたのでビックリしました。JavaScriptのthisのスコープは勘違いしやすい部分ですので助かります。
あとはSublimeTextにある関連ファイルの要素リンク機能(CSSなど)があれば私の用途としては完璧です。

今後はHTML+CSSの初期作成はSublime Textで、JavaScript記述とHTML+CSSのメンテナンスはVSCodeでという使い分けで行きます。

それと嵌っているJavaScript+Node.js+Electron(JNE:勝手に略号)の組み合わせが十分に実用的な事も事例をもって確認できましたので、今後は自信を持ってJNEでディスクトップアプリを作ろうと思います。何時になるかわかりませんが、ちゅんラヂのデスクトップアプリ化に挑戦して見ようと考えています。

| | コメント (0)