信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • テクログ

    NuxtJs

    皆さんこんにちは。本日はNuxtjsというものを少し触ってみます結構前ですが同じくブログでVueJsを紹介しました。↓https://core-tech.jp/blog/article196/NuxtJsはこれに対して機能を足してSSR(サーバサイドレンダリング)を可能にしたフレームワークのようです。これだけSPAサイトが流行っている中ですが、クローラにちゃんとキーワードを読ませたいよってなったらこういったSSRができるフレームワークを使わないといけませんね。では早速。Nodejsがインストール済で、NPM5.2以降が入っている前提で話をします。私はOSはMACOS(Mojave)です。コンソールで以下を入力します。npx create-nuxt-app sample 初期設定コンソールがでるので適当に好みにあったものを選択します。で、おわるとこんな感じのがでます。 To get started: cd sample npm run dev  To build & start for production: cd sample npm run build npm run start To get startedの手順をそのまま叩くと起動します。 cd sample npm run dev で、http://localhost:3000にアクセス。はいできた。ここで終わっても面白くはないので少しだけいじって体験してみます。作成したプロジェクトにはすでにGitまで入っているので一応登録しておきます。同じ場所でgit add . git commit :wq デザインの部分に関しては、今回はBootsnippさんにサンプルとしてあるhttps://bootsnipp.com/snippets/1ea0Nを使わせてもらいます。いじるファイルは2ファイル★変更点sample/nuxt.config.jsheadの部分をまるっとこの形にします。head: {   title: 'nuxt-example',   meta: [     { charset: 'utf-8' },     { name: 'viewport', content: 'width=device-width, initial-scale=1' },     { hid: 'description', name: 'description', content: 'Nuxt.js project' }   ],   script: [     { src: 'https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js' },     { src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js' }   ],   link: [     { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },     { rel: 'stylesheet', id: 'bootstrap-css', href: 'https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css' },     { rel: 'stylesheet', type: 'text/css', href: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css' },   ] }, これは、ページのヘッダなどを設定する部分で前回同様CDNでスタイルなど引けるようにしています。Sample/pages/index.vueまるっと下記を貼り付けます<template>   <div class="container">     <div class="messaging">       <div class="inbox_msg">         <div class="inbox_people">           <div class="headind_srch">             <div class="recent_heading">               <h4>Recent</h4>             </div>             <div class="srch_bar">               <div class="stylish-input-group">                 <input type="text" class="search-bar"  placeholder="Search" >                 <span class="input-group-addon">                 <button type="button"> <i class="fa fa-search" aria-hidden="true"></i> </button>                 </span> </div>             </div>           </div>           <div class="inbox_chat">             <div class="chat_list active_chat">               <div class="chat_people">                 <div class="chat_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>                 <div class="chat_ib">                   <h5>Coretec-Nuxt-Sample<span class="chat_date">Aug 6</span></h5>                   <p>テストのためのサンプルです</p>                 </div>               </div>             </div>             <div class="chat_list">               <div class="chat_people">                 <div class="chat_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>                 <div class="chat_ib">                   <h5>テストです<span class="chat_date">Aug 7</span></h5>                   <p>テスト部屋2番です</p>                 </div>               </div>             </div>           </div>         </div>         <div class="mesgs">           <div class="msg_history">             <div class="outgoing_msg">               <div class="sent_msg">                 <p>最初からいれてあるサンプルの部分です</p>                 <span class="time_date"> 11:01 AM    |    Today</span> </div>             </div>             <div class="incoming_msg">               <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>               <div class="received_msg">                 <div class="received_withd_msg">                   <p>最初からいれてあるサンプルの部分です                   </p>                   <span class="time_date"> 11:01 AM    |    Today</span></div>               </div>             </div>             <div v-for='(meg, index) in talks' :key='index' >               <div class="incoming_msg" v-if=meg.flg>                 <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>                 <div class="received_msg">                   <div class="received_withd_msg">                     <p>{{ meg.item }}</p>                     <span class="time_date">{{ meg.timestamp }}</span></div>                 </div>               </div>               <div class="outgoing_msg" v-else>                 <div class="sent_msg">                   <p>{{ meg.item }}</p>                   <span class="time_date">{{ meg.timestamp }}</span> </div>               </div>             </div>           </div>           <form v-on:submit.prevent>             <div class="type_msg">               <div class="input_msg_write">                 <input type="text" class="write_msg" placeholder="メッセージをいれてね" v-model="newItem" />                 <button class="msg_send_btn" type="button"><i class="fa fa-paper-plane-o" aria-hidden="true" v-on:click="addItem"></i></button>               </div>             </div>           </form>         </div>       </div>     </div></div> </template> <script>     export default {         data() {             return {                 newItem: '',                 talks: [],                 flg: false             }         },         methods: {             addItem: function(event) {               var val = this.flg               var todo = {                   item: this.newItem,                   timestamp:new Date(),                   flg:!val               };               this.flg = todo.flg               this.talks.push(todo)             }         }     } </script> <style>   .container {     min-height: 100vh;     display: flex;     justify-content: center;     align-items: center;     text-align: center;   }   .title {     font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */     display: block;     font-weight: 300;     font-size: 100px;     color: #35495e;     letter-spacing: 1px;   }   .subtitle {     font-weight: 300;     font-size: 42px;     color: #526488;     word-spacing: 5px;     padding-bottom: 15px;   }   .links {     padding-top: 15px;   }   .container{max-width:1170px; margin:auto;}   img{ max-width:100%;}   .inbox_people {     background: #f8f8f8 none repeat scroll 0 0;     float: left;     overflow: hidden;     width: 40%; border-right:1px solid #c4c4c4;   }   .inbox_msg {     border: 1px solid #c4c4c4;     clear: both;     overflow: hidden;   }   .top_spac{ margin: 20px 0 0;}   .recent_heading {float: left; width:40%;}   .srch_bar {     display: inline-block;     text-align: right;     width: 60%; padding:   }   .headind_srch{ padding:10px 29px 10px 20px; overflow:hidden; border-bottom:1px solid #c4c4c4;}   .recent_heading h4 {     color: #05728f;     font-size: 21px;     margin: auto;   }   .srch_bar input{ border:1px solid #cdcdcd; border-width:0 0 1px 0; width:80%; padding:2px 0 4px 6px; background:none;}   .srch_bar .input-group-addon button {     background: rgba(0, 0, 0, 0) none repeat scroll 0 0;     border: medium none;     padding: 0;     color: #707070;     font-size: 18px;   }   .srch_bar .input-group-addon { margin: 0 0 0 -27px;}   .chat_ib h5{ font-size:15px; color:#464646; margin:0 0 8px 0;}   .chat_ib h5 span{ font-size:13px; float:right;}   .chat_ib p{ font-size:14px; color:#989898; margin:auto}   .chat_img {     float: left;     width: 11%;   }   .chat_ib {     float: left;     padding: 0 0 0 15px;     width: 88%;   }   .chat_people{ overflow:hidden; clear:both;}   .chat_list {     border-bottom: 1px solid #c4c4c4;     margin: 0;     padding: 18px 16px 10px;   }   .inbox_chat { height: 550px; overflow-y: scroll;}   .active_chat{ background:#ebebeb;}   .incoming_msg_img {     display: inline-block;     width: 6%;   }   .received_msg {     display: inline-block;     padding: 0 0 0 10px;     vertical-align: top;     width: 92%;   }   .received_withd_msg p {     background: #ebebeb none repeat scroll 0 0;     border-radius: 3px;     color: #646464;     font-size: 14px;     margin: 0;     padding: 5px 10px 5px 12px;     width: 100%;   }   .time_date {     color: #747474;     display: block;     font-size: 12px;     margin: 8px 0 0;   }   .received_withd_msg { width: 57%;}   .mesgs {     float: left;     padding: 30px 15px 0 25px;     width: 60%;   }   .sent_msg p {     background: #05728f none repeat scroll 0 0;     border-radius: 3px;     font-size: 14px;     margin: 0; color:#fff;     padding: 5px 10px 5px 12px;     width:100%;   }   .outgoing_msg{ overflow:hidden; margin:26px 0 26px;}   .sent_msg {     float: right;     width: 46%;   }   .input_msg_write input {     background: rgba(0, 0, 0, 0) none repeat scroll 0 0;     border: medium none;     color: #4c4c4c;     font-size: 15px;     min-height: 48px;     width: 100%;   }   .type_msg {border-top: 1px solid #c4c4c4;position: relative;}   .msg_send_btn {     background: #05728f none repeat scroll 0 0;     border: medium none;     border-radius: 50%;     color: #fff;     cursor: pointer;     font-size: 17px;     height: 33px;     position: absolute;     right: 0;     top: 11px;     width: 33px;   }   .messaging { padding: 0 0 50px 0;}   .msg_history {     height: 516px;     overflow-y: auto;   } </style> で、何ができたかというと。一人でチャットできるWebアプリです(笑)初期画面こんな感じ『メッセージをいれてね』の部分に文字を入れて右の紙飛行機ボタンを押すと1人チャット完成です。処理部分に関して抜粋して書きます。Index.vueのHTML部分 <div class="mesgs">   <div class="msg_history">    <div class="outgoing_msg">     <div class="sent_msg">      <p>最初からいれてあるサンプルの部分です</p>      <span class="time_date"> 11:01 AM  |  Today</span> </div>    </div>    <div class="incoming_msg">     <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>     <div class="received_msg">      <div class="received_withd_msg">       <p>最初からいれてあるサンプルの部分です       </p>       <span class="time_date"> 11:01 AM  |  Today</span></div>     </div>    </div>    <div v-for='(meg, index) in talks' :key='index' >     <div class="incoming_msg" v-if=meg.flg>      <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>      <div class="received_msg">       <div class="received_withd_msg">        <p>{{ meg.item }}</p>        <span class="time_date">{{ meg.timestamp }}</span></div>      </div>     </div>     <div class="outgoing_msg" v-else>      <div class="sent_msg">       <p>{{ meg.item }}</p>       <span class="time_date">{{ meg.timestamp }}</span> </div>     </div>    </div>   </div>   <form v-on:submit.prevent>    <div class="type_msg">     <div class="input_msg_write">      <input type="text" class="write_msg" placeholder="メッセージをいれてね" v-model="newItem" />      <button class="msg_send_btn" type="button"><i class="fa fa-paper-plane-o" aria-hidden="true" v-on:click="addItem"></i></button>     </div>    </div>   </form>  </div> </div> Index.vueの処理部分<script>   export default {     data() {       return {         newItem: '',         talks: [],         flg: false       }     },     methods: {       addItem: function(event) {        var val = this.flg        var todo = {          item: this.newItem,          timestamp:new Date(),          flg:!val        };        this.flg = todo.flg        this.talks.push(todo)       }     }   } </script> buttonを押下した時にscriptのv-on:click="addItem"が発火。v-model="newItem”の値を入れてdataの変数を書き換え再描画しています。1メッセージごとにflgの中身を交互に切り替え自分と相手側が会話しているように表現しています。再描画部分は<div v-for='(meg, index) in talks' :key='index' >でループで出力し、<div class="incoming_msg" v-if=meg.flg>でHTMLを相互に切り替えています。わりと簡単な実装でチャットツールのような表現をすることができました。しっかりと作り込んでいけばもっと沢山のことができるかもしれませんね。本日はざっくり概要部分だけ触れました。それでは。
  • テクログ

    Vuejsって聞いたことある?

    こんちわ!新納です。突然ですが皆さんVue.jsって知ってます?読み方はビュージェーエスです。JSではいろんなライブラリが出ていますよね。その中でもjQueryは特に有名で使いやすいライブラリだと思います。個人的にも、jQuery大好きです。(簡単にかけるので)ですが、jQueryも簡単は書きやすい反面ミニマムな機能実装にはおすすめですが大規模、且つ複数のJSファイルに分かれるような状態になると中々メンテが大変な事になってきます。更に、あまり良いこととは言えませんがjQueryでは階層指定でバインドしている場合も多々あると思うので、うかつにHTMLをいじると既存処理が動かなくなったよーなんてことになったりします。.parent().parent.().children()……とかやっていると少しHTMLいじっただけで死ねますよねwまあ双方向バインディングとかVirtualDOMとかいろいろ特徴があるのでとくとくと説明していきたいところですが、今回はあまり概念には触れず超簡単なサンプルを使ってjQueryとの書き方の違いを比較したいと思います。コピペのまま動くようにしたいので今回はどちらのライブラリもCDNからロードしています。★やりたいこと痩せるためにはボタンを押したらリストの2番めの要素の文言を『昼はぬいてダイエット』に変える◆jQueryの場合-----------------------------------test_jquery.html<html lang="ja"> <head> <meta charset="UTF-8"> <title>てすと</title> </head> <body> <div id="content"> <input type="button" value="痩せるためには"> <ul> <li>朝ごはん</li> <li>昼ごはん</li> <li>晩ごはん</li> </ul> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="./test_jquery.js"></script> </body> </html> test_jquery.js$(function(){ $("#content input").on("click",function(){ $("#content ul li").eq(1).text("昼は抜いてダイエット"); }); }); -----------------------------------------------------------------------◆Vuejsの場合------------------------------test_vue.html<html lang="ja"> <head> <meta charset="UTF-8" /> <title>てすと</title> </head> <body> <div id="content"> <form> <input type="button" value="痩せるためには" v-on:click="ibentohakka" /> </form> <ul> <li v-for="gohan in list">{{ gohan }}</li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script> <script src="./test_vue.js"></script> </body> </html> test_vue.jsvar app = new Vue({ el: '#content', data: { list: [ '朝ごはん', '昼ごはん', '晩ごはん' ] }, methods: {  ibentohakka: function() { Vue.set(this.list, 1, '昼は抜いてダイエット'); } } }); ---------------------------------------------------------…どうすか?画面で見ると結果は全く同じです。『jQueryの方が記述短いじゃねーかいい加減にしろ!』とお怒りの方。ごもっともです…Vueは特徴的なところが何点かありますね。<input type="button" value="痩せるためには" v-on:click="ibentohakka" />これは、jQueryのonclickと似ています。これが押されたらjsに書いてあるmethodsのibentohakkaが発火し中の処理Vue.set(this.list, 1, '昼は抜いてダイエット’);が実行されます。<li v-for="gohan in list">{{ gohan }}</li>jQueryではHTMLに直接リストを記述しましたが、Vueはリストの部分にこれしかありません。これは、gohan in listの部分でデータ・セットの部分data: { list: [ '朝ごはん', '昼ごはん', '晩ごはん' ]},のリストをループして出力します。jQueryだと$("#content ul li").eq(1).text("昼は抜いてダイエット”);でdomを指定して値を書き換えていますが、これだと例えばulの要素が1つ上に追加されたら想定外の部分が書き換わってしまいます。ですが、Vueであれば<li v-for="gohan in list">{{ gohan }}</li>で作り出したものに対してVue.set(this.list, 1, '昼は抜いてダイエット');としているので、仮にHTMLの階層が変わってしまっても変更したい要素がうまく切り替わってくれます。この短いコードではあまりメリットを感じられないかもしれません。が、プロジェクト規模が大きくなり、HTMLの改修が増えるほどVueのメリットは大きくなってくると思っています。ライブラリを読むだけで使えるしjQueryとの共存もできるのでいきなり全書換は嫌だけど簡単な部分だけでもVueで記述していったらいつか良さに気づく日もくるんじゃないでしょうか。ではまた!
  • レビュー

    コアテックコーポレートが生まれ変わりました!

    コーポレートリニューアル後初投稿となります。つらつら社長の自己紹介しても仕方ないので端的に私は①入社7年目②プログラマ入社③この業界の前はコンサルです。昨年11月末に代表指名を受け社長に就任しました。代表になっても私自身はエンジニアとしての気持ちはずっともっていたいですし技術研鑽も今後もしていきます。エンジニアは水や電気と一緒でできて当たり前、動いていて当たり前の仕事で辛い時も沢山ありますが難しい機能やまだ誰もやったことの無い機能を実現し自分の成長を感じられたり、納期ギリギリで苦しい中一緒に仲間とたまにぶつかりつつも頑張り無事リリースできたり、お客様の想像通りの機能を実現して喜んでもらえる時は無上の喜びを得ることができます。今働いてくれているエンジニアの皆さんにはただ機械のように言われた機能を作るだけではなく上記のような喜びを仕事を通して感じ成長を実感してもらいたいし、多くのエンジニアの皆さんがそう感じられる環境を作っていくのが私のミッションです。創業時期から年々売上も利益も増収増益を繰り返しておりますし70名に拡大した今であってもありがたい事に各所から沢山の仕事のご依頼を頂いておりますが昨今の日本のエンジニア不足事情もあり需要に答えるために2018年5月に海外に子会社を設立しました。https://core-tech.tw/設立1ヶ月たたずして既に4名の入社が決まっており年内30名のエンジニア確保を目標として動いております。これからも多くの仲間と一緒に成長し多くのお客様の願いを叶えられるように動いていきたいと思っております。まあ…私はプログラマなので思うのかもしれませんがものづくりって本当に楽しいですよね!コアテックは今年で創立10周年を迎えます。10周年という記念の年にコーポレートサイトをリニューアルしたのは偶然ではありますが、制作会社である以上、発信し続ける姿勢は変わらず持っていたいと考えます。弊社が持っている技術・知識を発信しつつ、コーポレートサイトにて披露して参ります。
  • テクログ

    機械学習やっちゃうよ!

    こんにちは、ni-yoです。 世はAIというワードを日常的に目にするようになってきておりますが、今回は超簡単なサンプルからAIプログラムの世界に少し触れてみたいと思います。 今回は機械学習では非常にメジャーなライブラリであるscikit-learnに触れてみます。※本内容はni-yoが勝手に考えたケースなので、機械学習として適切な内容とは限りません。 pyhton3が入っていて、pip3が使える前提で話をしていきます ターミナルコマンドで以下を入力pip3 install -U scikit-learn scipy matplotlibデータ整理に使うモジュールも入れましょうpip install pandas ここまで入れればひとまず準備は完了です。Let’s 機械学習! 今回は、2つの値を与えて左の数値が大きければ0を返し、右の数値が大きければ1を返すという処理を想定します。最初にサンプルとしてデータと正解を与えて学習させるやり方を『教師あり学習』と言います。 また、最期に機械学習の予測結果が合っていたかを検証する処理を作っています。  教師データとするのは、以下のようなデータです。   [1,4,1], #右が大きいので1     [2,1,0], #左が大きいので0     [3,2,0], #左が大きいので0     [2,3,1],     [3,7,1],     [6,4,0]の1、2番目の数値が与えるデータ。3番目が正解データです。下記処理にて値を取り出しています data = df.ix[:,0:1] #与えるデータ label = df.ix[:,2] #データに対しての正解 ここで機械学習の基本、サポートベクターマシンを使うためのおまじないを唱えます clf = svm.SVC() サポートベクターマシンに、先程切り出したデータと答えを与えます。 これがいわゆる教師データになります。clf.fit(data,label) #学習させるclf.fitをして学習が終わったら、与えるデータと予測処理を呼びます与えるデータは、今回は少し多めに10コ与えて正解率をみていきます。yosokudata = [ [5,4], [0,1], [1,2], [6,3], [3,4], [2,0], [1,4], [0,2], [3,1], [7,1],]予測してくれるのは、predictという関数ですclf.predict(yosokudata)簡単ですが、上記を踏まえて完成した処理が以下です。最期に、予測結果があっているかどうかを検証する処理を付け加えます。 sample1.py-------------------------------------import pandas as pd from sklearn import svm,metrics input = [    [1,4,1],     [2,1,0],     [3,2,0],     [2,3,1],     [3,7,1],     [6,4,0] ] df = pd.DataFrame(input) data = df.ix[:,0:1] #DATA index label = df.ix[:,2] #DATA label clf = svm.SVC() clf.fit(data,label) #学習させる #予測する yosokudata = [     [5,4],     [0,1],     [1,2],     [6,3],     [3,4],     [2,0],     [1,4],     [0,2],     [3,1],     [7,1], ] yosoku = clf.predict(yosokudata) #予測実行 print("予測結果",yosoku) #検証します for index,kotae in enumerate(yosoku):     print(yosokudata[index][0],yosokudata[index][1],kotae)     if yosokudata[index][0] < yosokudata[index][1]:         seikai = 1     else:         seikai = 0     if seikai == kotae:         print("正解")     else:         print("不正解")—————————————さて…上記の結果はどうだったんでしょうか?スクリプトを叩いて結果を見てみます。python sample1.py予測結果 [0 0 1 0 1 0 1 1 0 0]5 4 0正解0 1 0不正解1 2 1正解6 3 0正解3 4 1正解2 0 0正解1 4 1正解0 2 1正解3 1 0正解7 1 0正解なんと…10問中9問の正解を叩き出しました。普通に0か1だったら50%の正解率になるはずなので、ちゃんと今回教師データから傾向を見出して予測してくれたみたいです。 今後、もっと色々なパターンで機械学習をためしていきたいと思います。
  • テクログ

    PHPとElasticTranscoder

    PHPとElasticTranscoder 皆さんこんにちわ。 ni-yoです。 本日も技術ネタを少々… 弊社はサーバの主流はAWSになっています。 構築の手間と冗長性等を考慮するとオンプレより多方面でメリットが大きく 手放せない存在になっています。 本日はそんな機能の1つElasticTranscoderの紹介をさせていただきます。 Webの世界もクラウド技術の発達等により昔は制限があって実装できないような コンテンツを実現できるようになってきました。 Webの世界もここ近年動画コンテンツの実装率が日々あがってきていることを感じます。 とはいえ、Webでの動画実装はそれほど簡単ではありません。 動画には画像よりもずっと多くの規格があり、(mp4/avi/wmv/flv等) 反面Webブラウザで再生できる規格にはある程度制限があります。 例えばYoutubeのようにユーザ投稿型のコンテンツを作ろうという場合、 ある程度ブラウザで再生できる規格に変換する必要性があります。 この作業をエンコードと言い、動画変換作業の中でデジタル映像をアナログ信号に デコードしないでエンコードを行う作業をトランスコードと言います。 今回紹介するElasticTranscoderはこのトランスコードの作業をAWSでできる技術です。 今回はWebで考えるのでPHPからElasticTranscoderへジョブ通知することにスポットし、 ElasticTranscoder自体は詳しく掘り下げません。 ざっと手順を言えば ①トランスコード元ファイルを配置するS3フォルダを作成 ②トランスコード済みファイルを配置するS3フォルダを作成 ③ElasticTranscoderの入力を①、出力を②で指定したパイプラインを作る ④ElasticTranscoderにアクセスできるIAMを作る。 ⑤IAMの鍵をPHPのソースに記載して①のS3にファイルアップ、パイプラインに変換指示を送る ⑥パイプラインがトランスコード処理を行い、出力先にトランスコード済みファイルが配置される。 のような手順です。 ⑤の部分のPHPプログラムは例えば下記のようになります。 public function getInstance() {         $this->obj = null;         if (is_null($this->obj)) {             $this->obj = Aws::factory([                 'key'    => (IAMで設定したkey),                 'secret' => (IAMで設定したパスワード),                 'region' => Region::TOKYO             ])->get('ElasticTranscoder');         }         return $this->obj;     }     public function createJob($args) {         try {             $res = $this->getInstance()->createJob($args);         } catch (Exception $e) {             echo $e->getMessage();             return false;         }         return $res;     }          public function transcode() {           $result = $this->createJob([             'PipelineId' => (③で作成したパイプラインのID),             'Input' => [                 'Key' => (入力S3に配置したファイルパス),             ],             'Outputs' => [                 // mp4 & Thumbnail                 [                     'Key'              => (出力先に配置したいファイルパス),                     'PresetId'         => '1351620000001-100070',                     'ThumbnailPattern' =>(入力S3に配置したファイルパス)."-{count}"                 ],                 // webm                 [                     'Key'             => $mp4Keyfile.'.webm',                     'PresetId'        => '1351620000001-100240',                 ]             ],         ]);     } transcode関数をコールした時点で入力用S3には動画ファイルを置かれている前提です。 これで、出力したいファイルパスにはmp4とwebmという形式で変換された動画が配置されるはずです。 今回は例としてmp4とwebm形式を指定しています、PCとスマートフォンの対応という部分を考えれば この2つのフォーマットを作成すればほぼカバーできると思います。 もし、それ以外の形式で出力したければ 'PresetId'         => '1351620000001-100070', をそれに準じたものに変更すれば出力されます。 この出力形式はプリセットと呼び、出力したい最適なものを https://docs.aws.amazon.com/ja_jp/elastictranscoder/latest/developerguide/system-presets.html から選択して使用するか、細かい設定をしたければ自作でプリセットを作成することができます。 簡単ですが以上です。 今まで動画配信業者等を使わなくては実現できなかった部分が自前でできるので日々技術進歩を感じますね。 それでは (^-^)ノ
  • テクログ

    Database:Mysqlがめっちゃ重い時

     こんにちは、ni-yoです。すごく開発者向けな話になりますが、MysqlのDBが応答返せないくらいめっちゃ重い。モニターするとDBのCPUやメモリが異常に高騰している…とかありますよね。 その時に負荷の原因となり得る時間がかかっているクエリを探すためには、SHOW FULL PROCESSLISTというコマンドが便利です。 MYSQLのSQLを発行する画面でSHOW FULL PROCESSLIST;を実行! 出てくる一覧としては、idUSERHostdbCommandTimeStateInfoがでてきます。 IDはプロセスIDUserはMysqlの実行ユーザ名Hostは接続元dbは対象のデータベースTimeは実行している時間(秒)Stateは実行している状態(init処理、データ送信処理等の状態)Infoは実行しているモノ(主にSQL)です。 見方はわりとシンプルにCommandがQuery且つTimeが異常に高い値(数十秒を超えている等)を探します。そういったSQLがあった場合例えばIndex不足で異常に処理時間がかかっていたりという可能性があります。 もしそれがあった場合、Infoに書いてあるSQLを確認して、どの処理から発行されたSQLなのか、そのSQLは正しいSQLなのかを確認しておくと後に同様の事象が発生する事を抑止することができますが、どちらにせよそういった原因となるSQLがいつまでも動いていては負荷の原因が取り除かれませんので、勇気を持ってMysql上から問題のプロセスを取り除きます。 SHOW FULL PROCESSLISTで下記のような時間がかかっているSQLが発見された場合(Timeが300なので5分間応答が返ってきていない)45384100 root (発行元IPアドレス):(ポート番号) (テーブル名) Query 300 Sending data SELECT DISTINCT…(省略) KILL (プロセス番号)で上記SQLの実行を停止できます。 プロセス番号は一番左のカラムになりますので、勇気を持って下記コマンドを実行します!KILL 45384100をたたくと、他の動作には影響を与えず上記問題のSQLの実行を強制停止できます。(Windowsのタスクマネージャにあるプロセスを落とすのと同じような感じです) 何か異常に時間がかかる場合は上記処置で負荷は改善されるかと思います。 負荷の原因は一概に言えませんが、例えばSHOW PROCESSLISTでプロセスが100個とか出てくるのは基本的には異常であると見なせると思います。 例えば月1千万PVあるサイトだったとしても、1秒で考えれば10,000,000 ÷ 30(日) ÷ 24(時間) ÷ 60(分) ÷ 60(秒) ≒ 4回/秒ということなので、もちろんピーク時間のなどはありますが慣らすと1秒に4回程度の閲覧になるはずです。 ユーザページで様々なSQLを発行しているとしても大概のWebサイトはシングルスレッドで1つのSQLが終わったら次を発行の動作しているとは思うのでSQLの個数を考えるとしたら概ね10個以内に収まるはずです。 月数億PVも行くような超大手のようなサイトでは上記の考えはあてはまりませんが、月1千万PV程度にも満たないサイトがプロセスが100個以上いくような場合には、Mysqlのコネクションが切れない(もしくは不必要に長い)設定がサーバにしてある。DosやDDos等通常ありえない大量のリクエストが送信されている。等の部分を確認する必要があるかもしれません。  それでは(* ̄▽ ̄)ノ~~ マタネー♪