Planet TLWG

Subscribe to Planet TLWG feed
Planet TLWG - http://debianclub.org/planet-tlwg
Updated: 11 min 39 sec ago

LookHin: สร้างจาร์วิสได้ง่ายๆ ด้วย Raspberry Pi + Snowboy

23 April, 2017 - 09:54

ฝันไว้ว่าอยากทำระบบที่สามารถคุยตอบโต้กับคอมพิวเตอร์แบบจาร์วิสใน IRON MAN มานานแล้วครับ แต่ก็ได้แค่ฝันเพราะผมเองก็ไม่มีความสามารถที่จะทำได้ขนาดนั้น แต่เราก็ยังพอจะสร้างจาร์วิสแบบโง่ๆ ด้วยงบประมาณไม่มากขึ้นมาจาก Raspberry Pi ได้เช่นกันครับ โดยสิ่งที่เราต้องมีก็คือ Raspberry Pi + ลำโพง + ไมโครโฟน โดยเราจะใช้โปรแกรมที่ชื่อว่า Snowboy Hotword Detection ข้อดีของเจ้าตัวนี้ก็คือว่ามันฟรีสำหรับ hacker อย่างเรา และสามารถสร้างโมเดลของคำที่ต้องการได้ไม่ยาก ซึ่งเจ้า Snowboy เนี้ยก็มี library ให้ใช้ได้อยู่หลายภาษาตามแต่ถนัดเลยครับ แต่ภาษาที่เราจะใช้เขียนวันนี้จะใช้เป็น Node.js

อย่างแรกเลย เตรียมอุปกรณ์ต่างๆ ให้เรียบร้อย Raspberry Pi + ลำโพง + ไมโครโฟน

ก่อนลงมือทำอย่างอื่นให้ทำการอัพเดทระบบก่อนครับ

sudo apt-get update
sudo apt-get upgrade

จากนั้นทำการติดตั้ง Node.js และติดตั้ง developer tools ต่างๆ ให้พร้อมใช้งาน

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install nodejs
sudo apt-get install sox libmagic-dev libatlas-base-dev
sudo apt-get install build-essential

กำหนด NODE_PATH เพื่อให้เรียกใช้งานโมดูลของ Node.js ที่ติดตั้งแบบ global ได้ เพราะเดียวเราจะติดตั้งโมดูทั้งหมดเป็นแบบ global

export NODE_PATH=/usr/lib/node_modules

เมื่อติดตั้งเสร็จแล้ว ลองเช็คดูก่อนว่าสามารถเรียกใช้คำสั่ง node และ npm ได้ปกติแล้ว ง่ายๆ ก็ลองสั่งให้แสดง version ขึ้นมาดูก่อนเลย

node -v
npm -v

ขั้นตอนถัดไปให้ทำการคอนฟิกและทดสอบลำโพงกับไมโครโฟน แต่ก่อนอื่นเราต้องทราบก่อนว่าทั้งลำโพงและไมโครโฟนมันต่ออยู่ที่ card id และ device id อะไร เพราะเดียวเราต้องใช้ทั้ง card id และ device id ตัวนี้ในการคอนฟิกในขั้นตอนถัดไป

ตรวจสอบหมายเลข card id และ device id ของลำโพง

aplay -l

จากรูปจะเห็นว่ามี card อยู่หลายใบ ให้สั่งเกตุหมายเลข card id และ device id ที่ผมไฮไลท์เอาไว้ด้วยนะครับ ให้เลือกใช้ card id และ device id อันที่ลำโพงเราต่ออยู่ (ข้างหลังมันมีชื่อรุ่นบอก น่าจะพอเดาได้อยู่)

ตรวจสอบหมายเลข card id และ device id ของไมโครโฟน

arecord -l

ทำการสร้างไฟล์ ~/.asoundrc เพื่อกำหนดค่า default ของลำโพงและไมโครโฟนให้ระบบ

nano ~/.asoundrc

โดยให้พิมพ์คำสั่งตามนี้ลงไป จะเห็นว่าในช่องของ playback.pcm ซึ่งก็คือลำโพงของเรา ให้เราใส่ hw:1,0 ซึ่งเป็นหมายเลข card id , device id ในที่นี้ก็คือ card 1, device 0 และสำหรับ capture.pcm ซึ่งเป็นไมโครโฟน ให้เราใส่เป็น hw:1,0 ซึ่งก็คือไมโครโฟนจาก card 1, device 0 (ถ้าหาก card id และ device id ของท่านแตกต่างจากนี้ก็ให้ใส่ให้ตรงกับของตัวเองด้วยนะครับ)

pcm.!default {
  type asym
   playback.pcm {
     type plug
     slave.pcm "hw:1,0"
   }
   capture.pcm {
     type plug
     slave.pcm "hw:1,0"
   }
}

เราสามารถปรับความดังของลำโพงและไมโครโฟนได้โดยใช้คำสั่ง alsamixer (ถ้าท่านใช้ตัวแปลง USB To Sound Adapter เพื่อทำการแปลงสาย USB เป็น 3.3mm เพื่อใช้เสียบลำโพงกับไมโครโฟนแบบผม ก็ให้กด F6 เพื่อเลือก device ก่อนนะครับ)

alsamixer

ทำการทดสอบการบันทึกเสียงจากไมโครโฟน ให้สั่ง rec test.wav และพูดใส่ไมโครโฟนและถ้าต้องการหยุดให้กด CTRL+C

rec test.wav

ลองสั่ง play เสียงที่เราบันทึกไว้เมื่อสักครู่นี้

aplay test.wav

ขั้นตอนถัดไปให้ทำการติดตั้ง snowboy และโมดูลต่างๆ ที่ต้องใช้งาน โดยเราจะติดตั้งทั้งหมดเป็นแบบ global ไปเลยนะครับ

sudo npm install -S -g snowboy
sudo npm install -S -g node-record-lpcm16
sudo npm install -S -g play-sound

ต่อไปเป็นการสร้างโมเดลเสียงของคำที่ต้องการ โดยให้เข้าไปที่ https://snowboy.kitt.ai/dashboard จะเห็นปุ่ม Create Hotword คลิกเลยครับ

ทำการตั้งชื่อและเลือกภาษาให้เรียบร้อย แต่ระบบยังไม่มีภาษาไทยให้เลือกนะ ให้เราเลือกเป็น Other ไปก่อนนะ ผมลองแล้วก็ได้เหมือนกัน

ขั้นตอนถัดไปเป็นการบันทึกเสียง ให้เราบันทึกเสียงของคำที่เราต้องการลงไป 3 ครั้ง

ขั้นตอนสุดท้ายเป็นการทดสอบและดาวน์โหลดโมเดลเสียงของเรา โดยเราจะได้มาเป็นไฟล์ .pmdl ดาวน์โหลดมาเก็บไว้ให้เรียบร้อยครับ

หลังจากติดตั้งโปรแกรมและสร้างไฟล์โมเดลของเสียงเรียบร้อยแล้วให้ทำการดาวน์โหลดโค้ดที่ผมเตรียมไว้ไปทดสอบรันได้เลยครับ Download Showboy Example โดยในโค้ดตัวอย่างจะมีไฟล์ snowboy.js ให้ทำการเปิดโค้ดขึ้นมาดูก่อนเลยครับ จะเห็นว่าในตัวอย่างผมมีโมเดลของคำสั่งเสียงอยู่ 2 ตัวคือ thai-hello.pmdl และ thai-what-is-your-name.pmdl ให้เอาโมเดลเสียงของตัวเองมาแทน 2 ไฟล์นี้นะครับ

snowboy.js

const record = require('node-record-lpcm16');
const Detector = require('snowboy').Detector;
const Models = require('snowboy').Models;
const player = require('play-sound')(opts = {})


const models = new Models();

models.add({
    file: 'thai-hello.pmdl',
    sensitivity: '0.5',
    hotwords: 'Hello'
});

models.add({
    file: 'thai-what-is-your-name.pmdl',
    sensitivity: '0.5',
    hotwords: 'What\'s your name'
});

const detector = new Detector({
    resource: "common.res",
    models: models,
    audioGain: 2.0
});

detector.on('silence', function() {
    //console.log('silence');
});

detector.on('sound', function() {
    //console.log('sound');
});

detector.on('error', function() {
    //console.log('error');
});

detector.on('hotword', function(index, hotword) {
    console.log('Index='+index+', Hotword='+hotword);

    if(index == 1){
      player.play('sound-hello.wav', function(err){
        //console.log('play sound');
      });
    }else if(index == 2){
      player.play('sound-my-name.wav', function(err){
        //console.log('play sound');
      });
    }
});

const mic = record.start({
    threshold: 0,
    verbose: false
});

mic.pipe(detector);

เรียบร้อยแล้วครับ ให้สั่งรัน node snowboy.js และพูดคำสั่งที่เราตั้งไว้ได้เลยครับ

node snowboy.js

หากติดขัดปัญหาใดค้นหาข้อมูลเพิ่มเติมจาก Google และอ่านรายละเอียดได้จากแหล่งอ้างอิงครับ

อ้างอิง :
https://snowboy.kitt.ai/
http://docs.kitt.ai/snowboy/
https://github.com/kitt-ai/snowboy
https://www.npmjs.com/package/snowboy

Kitt: มหาสงกรานต์ ๒๕๖๐

11 April, 2017 - 12:55
สงกรานต์ปี 2560 เป็นปี จ.ศ. (2560 – 1181) = 1379 วันเถลิงศก ตรงกับ (1379 * 0.25875) + floor(1379 / 100 + 0.38) – floor(1379/ 4 + 0.5) – floor(1379 / 400 + 0.595) – 5.53375 = 356.81625 + 14 – 345 – 4 – 5.53375 = 16.2825 = วันที่ 16 เมษายน 2560 เวลา 06:46:48 วันสงกรานต์ ตรงกับ 16.02375 – 2.165 = … Continue reading มหาสงกรานต์ ๒๕๖๐ →

bact: Visualizing power relations of actors (in Data Protection Bill)

11 April, 2017 - 11:28

This whole week I will participate in Internet Policy and Advocacy: Research Methods Workshop for South and Southeast Asia Actors at National Law University Delhi. (Nice way to spend my Songkran :p)

This is a presentation that I gave yesterday during the Case Study 1: The Power of Mapping Stakeholders, Decision Makers, and Implementers in Thailand’s Cyber Policy session, where we discussed examples of visualizing bills in graph (noun –verb-> noun), how this method can quickly reveal unbalanced power relations of actors(-to-be), and show why data protection mechanism in the current bill is probably structurally designed to fail.

Of course, the examples only rely on one type of source (written laws). Ideally, getting data from other types of source (actual enforcement, unspoken rules, policy stakeholders, etc.) is encouraged, for a more complete picture.

Draw.io is a nice online drawing tool that you may like to try. No installation is required. Graph can also be drawn in a descriptive way using tools like GraphvizGephi and NodeXL.
วาดกราฟความสัมพันธ์ระหว่างผู้กระทำ (actor) ในกฎหมาย

bact: คุยกับกระทรวงดิจิทัลเรื่องร่างพ.ร.บ.คุ้มครองข้อมูลส่วนบุคคล

5 April, 2017 - 06:22

เมื่อวานไปสำนักงานปลัดกระทรวงดิจิทัล ให้ข้อมูลเรื่องร่างพ.ร.บ.คุ้มครองข้อมูลส่วนบุคคล มีหลายประเด็นที่เขาคุยกันในที่ประชุม ก็ไล่ไปตามหัวข้อที่ทางกระทรวงเขากำหนดมา ในช่วงท้ายก่อนจบเขามีเปิดให้พูดถึงประเด็นอื่นที่เป็นห่วงด้วย

เรื่องที่คุยกัน เช่น

  • ควรเพิ่มนิยามของคำว่า “ผู้ประมวลผลข้อมูล” (data processor) หรือไม่ แตกต่างจาก “ผู้ควบคุมข้อมูล” (data controller) อย่างไร
  • อะไรคือ Legitimate Interests ที่จะอนุญาตให้ผู้ควบคุมข้อมูลสามารถประมวลผลข้อมูลได้แม้ไม่ตรงตามวัตถุประสงค์ที่เจ้าของข้อมูลให้ความยินยอมไว้เมื่อคราวที่เก็บรวบรวมข้อมูล
  • มีความต้องการนำข้อมูลไปวิเคราะห์ (เช่นในลักษณะ Big Data) หากได้ทำให้ข้อมูลเชื่อมโยงกลับมาระบุตัวบุคคลไม่ได้แล้ว ยังจะต้องขอความยินยอมอีกหรือไม่ (เรื่องนี้เคยพูดไปบ้างแล้ว โดยยกตัวอย่างข้อมูลสุขภาพ อ้างงานของ Sweeney (2000))
  • จะทำอย่างไรกับข้อมูลที่เก็บรวบรวมมาก่อนกฎหมายคุ้มครองข้อมูลประกาศใช้ – ให้ใช้ต่อไปได้เลยโดยไม่ต้องขอความยินยอมใหม่? หรือต้องขอใหม่? หรือกำหนดระยะผ่อนผันให้ใช้ได้ไประยะเวลาหนึ่ง แต่ถ้าพ้นช่วงนี้แล้วไม่ได้รับความยินยอมใหม่ ก็ต้องหยุดใช้และทำลายข้อมูลทิ้ง?
  • การกำหนดข้อยกเว้นหรือกำหนดให้กิจการใดที่ไม่อยู่ใต้บังคับของกฎหมายนี้
  • หลักการของ EU General Data Protection Regulation และ APEC Privacy Framework รวมถึง APEC Cross Border Privacy Rules (CBPR) system

และมีอีกบางประเด็นที่ไม่ได้คุยระหว่างประชุม แต่กลับมาค้นเพิ่ม เช่นนิยาม “profiling” ของ GDPR และการพรางข้อมูล (data masking/data obfuscation)

เอกสารนี้รวมความคิดเห็นบางส่วนของผมที่ได้อภิปรายไปเมื่อวาน (4 เม.ย. 2560) และเขียนเพิ่มเติมเพื่อส่งให้กับทางกระทรวงเป็นเอกสารอีกครั้งในวันนี้ (5 เม.ย. 2560) การแบ่งหัวข้ออิงตามคำถามที่กระทรวงถามมา และเพิ่มบางประเด็นที่ผมเห็นว่าแม้ไม่ได้ถามก็ควรอธิบายประกอบไปด้วยเพราะสำคัญ เช่น การออกแบบโครงสร้างคณะกรรมการคุ้มครองข้อมูล ซึ่งผมมองว่าตามร่างปัจจุบันคณะกรรมการจะไม่เป็นอิสระและจะทำงานไม่ได้ดี

ข้อมูลประกอบการนำเสนอความเห็นและข้อเสนอแนะ แนวทางแก้ไขหรือปรับปรุง ร่างพระราชบัญญัติคุ้มครองข้อมูลส่วนบุคคล พ.ศ. …. PDF | OpenDocument Text

ใครมีความคิดเห็นอะไรกับตัวร่าง (ขณะนี้ใช้ร่างฉบับที่สำนักงานคณะกรรมการกฤษฎีกาตรวจพิจารณาแล้ว เรื่องเสร็จที่ 1135/2558ในการพิจารณา) ก็ส่งความคิดเห็นไปได้ที่ คณะทำงานร่างแก้ไขกฎหมาย กระทรวงดิจิทัลเพื่อเศรษฐกิจและสังคม — ทางคณะทำงานแจ้งว่าทางเขามีกำหนดส่งเรื่องออกไปภายในเดือนเมษายนนี้ ก็เหลือเวลาอีกไม่มากแล้วครับ

LookHin: การสตรีมไฟล์วิดีโอไปยัง Facebook Live และ Youtube Live ด้วย FFmpeg

30 March, 2017 - 07:46

วันนี้มาทดลองทำการสตรีมไฟล์วิดีโอเพื่อถ่ายถอดสดไปยัง Facebook Live และ Youtube Live กันครับ โดยเราจะใช้ FFmpeg ในการสตรีม ไม่สอนการติดตั้งนะครับน่าจะพอทำเป็น โดยบน Facebook เราจะสตรีมทั้งจากหน้า profile และหน้า page ก่อนนี้เฟสบุคจะมี Publishing Tools ให้เฉพาะกับหน้า page เท่านั้น ถ้าจะสตรีมผ่านหน้า profile เราต้องเขียนโปรแกรมขึ้นมาเพื่อหาค่า Stream Key ซึ่งก็ไม่ได้ยากอะไร แต่ตอนนี้ไม่ต้องเขียนหละเฟสบุคเขาทำให้หมดแล้ว คลิกๆ ไม่กี่ทีก็ได้ Stream Key มาใช้แล้วครับ ส่วนของ Youtube ก็เช่นกัน คลิกๆ ไม่กี่ทีก็ได้ Stream key มาใช้สำหรับสตรีมเช่นกัน

1. การสตรีมวิดีโอไปยัง Facebook Live (Profile Account)
อันนี้เป็นการใช้แอคเค้าเฟสบุคธรรมดาของเรานี้หละครับ ซึ่งปกติเราก็กดถ่ายถอดสดจากมือถือหรือจากคอมพิวเตอร์ได้อยู่แล้ว แต่เดียวเราจะลองถ่ายถอดสดจากไฟล์หนังกันดูครับ เริ่มแรกให้เข้าไปที่ https://www.facebook.com/live/create/ และทำการคลิก Create Live Stream

เลือก Share on your own Timeline และคลิก Next

จากนั้นเราจะได้หน้าที่แสดง Server URL และ Stream Key ให้ copy ค่านี้เอาไว้ เดียวเราต้องใช้ในการสตรีม

เมื่อได้ Stream Key มาแล้ว เราก็มาสั่งสตรีมจาก ffmpeg ได้เลยครับ โดยให้สั่ง

ffmpeg -re -i test.mp4 -acodec libfdk_aac -ac 1 -vcodec libx264 -f flv "rtmp://rtmp-api.facebook.com:80/rtmp/XXXXXXXXXXXXX?ds=1&s_l=1&a=ZZZZZZZZZZZZZZ"

เรียบร้อยครับ กด Go Live ได้เลย

2. การสตรีมวิดีโอไปยัง Facebook Live (Page Account)
อันนี้เป็นการใช้แฟนเพจแอคเค้าในการสตรีมนะครับ เพสบุคเขาเตรียมเครื่องมือเอาไว้ให้พร้อมแล้วเช่นกัน โดยเริ่มจากการเข้าไปในหน้าเพจของเราแล้วคลิกที่ Publishing Tools และเลือก Video Library ทางเมนูซ้ายมือ จากนั้นคลิกที่ปุ่ม + Live

ได้ Stream Key มาแล้ว กด Next

สั่งสตรีมด้วยคำสั่งต่อไปนี้ อย่าลืมแก้ Stream Key เป็นของตัวเองให้เรียบร้อยนะครับ

ffmpeg -re -i test.mp4 -acodec libfdk_aac -ac 1 -vcodec libx264 -f flv "rtmp://rtmp-api.facebook.com:80/rtmp/XXXXXXXXXX?ds=1&s_l=1&a=ZZZZZZZZZZ"

กด Go Live เป็นอันเรียบร้อย

3. การสตรีมวิดีโอไปยัง Youtube Live
อันสุดท้ายเป็นการสตรีมไปยัง Youtube Live ให้เข้าไปที่ https://www.youtube.com/live_dashboard ให้เลื่อนลงมาล้างสุดจะเห็นหัวข้อ ENCODER SETUP ให้ทำการกด Reveal ระบบจะแสดง Stream name/key โดยในส่วนของ Share คือ Link ที่ใช้สำหรับดูไลฟ์จริง ส่งตัวนี้ให้เพื่อนได้เลยครับ ส่วนพารามิเตอร์ตัวอื่นๆ อย่างเช่นการใส่ภาพ thumbnail ก็ลองไปซนดูกันต่อเองครับ

จากนั้นนำ Stream name/key ที่ได้มาสั่งให้ FFmpeg สตรีมไปยัง Youtube Live โดยใช้คำสั่งต่อไปนี้

ffmpeg -re -i test.mp4 -acodec libfdk_aac -ac 1 -vcodec libx264 -f flv "rtmp://a.rtmp.youtube.com/live2/XXXX-XXXXX-XXXXX-XXXXX"

เรียบร้อยไลฟ์ได้แล้วครับ สำหรับข้อมูลเพิ่มเติมดูได้จากอ้างอิงด้านล่างนะครับ

อ้างอิง:
https://www.facebook.com/live/create/?step=landing
https://www.youtube.com/live_dashboard
https://ffmpeg.org/ffmpeg.html
https://www.facebook.com/facebookmedia/get-started/live

bact: กฎหมายคุ้มครองข้อมูลไทย จะเดินตามโมเดลไหนดี: สหภาพยุโรป หรือ เอเปค?

23 March, 2017 - 17:21

เวลาคุยกันว่า ประเทศไทยควรจะเลือกเดินตามหลักการคุ้มครองข้อมูลส่วนบุคคลของ EU (สหภาพยุโรป) หรือ APEC (ความร่วมมือทางเศรษฐกิจเอเชีย-แปซิฟิก) ก็มักจะมีคำอธิบายว่า ของ EU นั้นเน้นเรื่องสิทธิมนุษยชน แต่ของ APEC มองเรื่องเศรษฐกิจนะ (แล้วโน้มน้าวโดยนัยว่า ไทยน่าจะมองเรื่องเศรษฐกิจก่อน ตอนนี้เศรษฐกิจแย่)

ผมก็เคยอธิบายแบบเร็วๆ อย่างนั้นเหมือนกันนะ คือในแง่ที่มามันก็น่าจะทำนองนั้น

แต่ไม่ได้หมายความว่ากรอบกฎหมายของ EU มันไม่ได้คำนึงถึงเรื่องเศรษฐกิจเลย มันก็คิดในทุกมิติ เศรษฐกิจก็เป็นหนึ่งในนั้น นวัตกรรม ความก้าวหน้าทางวิทยาศาสตร์ก็ใช่ (เอาจริงๆ ก็พอพูดได้ว่า EU นี่เริ่มต้นด้วยเหตุผลทางเศรษฐกิจ ย้อนไปสมัยประชาคมถ่านหินและเหล็กกล้าแห่งยุโรป)

เราไม่จำเป็นต้องเลือกอย่างใดอย่างหนึ่ง สิทธิมนุษยชนกับเศรษฐกิจทั้งสองอย่างนี้ไปด้วยกันได้ โดยเฉพาะเศรษฐกิจดิจิทัลที่มันต้องตั้งอยู่บนฐาน “ความไว้เนื้อเชื่อใจกัน”

ถ้าเอาเศรษฐกิจอย่างเดียวไม่สนสิทธิมนุษยชนเลย ลองดูอุตสาหกรรมอาหารทะเลสิ ตอนนี้เป็นยังไง พอจะโดนแบนจริงๆ ก็ต้องรีบมาทำให้มันได้มาตรฐานอยู่ดี ตลาดที่เสียไปแล้วบางส่วนก็เสียไปเลย

การมีมาตรฐานด้านสิทธิที่ดี ก็เพื่อให้คู่ค้าของเราไว้ใจเรา เชื่อใจเรา ว่าเราให้ความสำคัญกับคุณค่าที่เขาให้ความสำคัญ มันแยกกันไม่ขาด

….

อีกประเด็นคือ ของ EU ที่เราคุยกันเนี่ย อันนึงคือ General Data Protection Regulation (Regulation (EU) 2016/679) กับอีกอันคือ Directive (EU) 2016/680 ซึ่งทั้งคู่เพิ่งออกมาเมื่อปีที่แล้ว (2016 และจะมีผลบังคับใช้ในปี 2018)

ในขณะที่ APEC Privacy Framework ออกเมื่อปี 2005 (เริ่มร่างปี 2003 adopted ปี 2004 แต่ finalized ปี 2005)

ตอนปี 2005 นี่โลกเทคโนโลยีสารสนเทศเป็นอย่างไรบ้าง?

  • hi5 กำลังเริ่มเป็นที่นิยม (ตั้งปี 2004)
  • MySpace เป็นสื่อสังคมออนไลน์อันดับหนึ่ง (ตั้งปี 2003)
  • Facebook เพิ่งตั้งได้ปีเดียว (2004) แต่ยังจำกัดสมาชิกอยู่เฉพาะนักศึกษาในสหรัฐ (เปิดให้ลงทะเบียนทั่วไปปี 2006)
  • Gmail ก็เพิ่งเปิดให้บริการแบบจำกัดได้หนึ่งปีเหมือนกัน (2004) ต้องมี invite ถึงจะสมัครได้ และกว่าจะเปิดให้บริการทั่วไปก็ปี 2009
  • โทรศัพท์ “สมาร์ตโฟน” ในตอนนั้นคือ Nokia รุ่น 9300i (ประกาศพ.ย. 2005 วางขายจริง ม.ค. 2006) ระบบปฏิบัติการ Symbian 7.0S หน่วยความจำ 80 MB เบราว์เซอร์รองรับ HTML 4.01 กับ WML 1.3 ราคาเกือบสามหมื่น
  • ยังไม่มี iPhone (ออกปี 2007)
  • ยังไม่มี Google Android (กูเกิลซื้อบริษัทแอนดรอย์มาปี 2005 แล้วเอามาพัฒนาต่อ แล้วออกรุ่นแรกในปี 2008)
  • ยังไม่มี Line (ออกปี 2011)
  • ยังไม่มี Amazon Web Services (เริ่มปี 2006)

คือหยิบมือถือของเราขึ้นมาดูนี่ แทบไม่มีอะไรที่มีมาก่อนปี 2005 เลย หรือถ้ามีก็เปลี่ยนสภาพไปจนจำไม่ได้แล้ว พวกคอนเซปต์อย่าง cloud อะไรนี่ สมัยนั้นยังไม่มีการใช้อย่างแพร่หลายในทางการค้าเลย (เมื่อก่อนเรียกในชื่ออื่น เช่น utility computing)

ซึ่งพอเป็นแบบนี้ มันก็ลำบากอยู่เหมือนกัน ที่จะคาดหวังให้กรอบกฎหมายจากปี 2005 อย่าง APEC Privacy Framework มันจะมาเห็นประเด็นอะไรในปัจจุบันแบบละเอียดๆ คือสมัยนั้นมันยังไม่มี (เอาจริงๆ มันก็พอมี เช่น APEC Cross-border Privacy Enforcement Arrangement จากปี 2010 แต่เราไม่ยอมอ้างกัน ไปอ้างแต่ของเก่า)

ในขณะที่ตอนร่าง General Data Protection Regulation ของ EU มันก็มีกรณีศึกษาอะไรให้สรุปเป็นบทเรียนเยอะแล้ว โดยเฉพาะจากอุตสาหกรรมอินเทอร์เน็ตและการประมวลผลข้อมูลที่มันเปลี่ยนไปอย่างมากในทศวรรษที่ผ่านมา เขาเลยปรับปรุงออกมาแบบนี้

ถ้าไทยจะมีกฎหมายใหม่ ก็ควรคิดถึงอนาคตไหม ไม่ใช่เอาวิธีคิดจากเมื่อ 12 ปีที่แล้วมาใช้ ประกาศปุ๊บ ล้าสมัยทันที เสียเวลาไหม

 

ภาพประกอบ: Nokia 9300i จาก Nokia Museum

bact: ออกแบบหน่วยงานคุ้มครองข้อมูลที่มีประสิทธิภาพ: บทเรียนจากสหภาพยุโรป

23 March, 2017 - 17:00

สรุปบางส่วนจากรายงานศึกษาเปรียบเทียบ Data Protection in the European Union: the role of National Data Protection Authorities (Strengthening the fundamental rights architecture in the EU II) ของ European Union Agency for Fundamental Rights [พ.ค. 2010]

วิธีปฏิบัติที่ดีที่สุด (best practices) สำหรับหน่วยงานคุ้มครองข้อมูล (Data Protection Authority) ว่าด้วยโครงสร้างขององค์กร, อำนาจ, ทรัพยากร, และความร่วมมือกับองค์กรอื่น

ในด้านหนึ่ง รัฐสมาชิกสหภาพยุโรปหลายแห่งได้มอบอำนาจเจาะจงบางประการและมอบอิสระอย่างสูงให้กับหน่วยงานคุ้มครองข้อมูล ในอีกด้านหนึ่ง หน่วยงานคุ้มครองข้อมูลก็ได้สร้างความร่วมมือกับผู้มีส่วนได้เสีย 3 ประเภท อันได้แก่ สถาบันของรัฐ หน่วยงานที่ไม่ใช่รัฐที่ทำงานแข็งขันในด้านนี้ และหน่วยงานคุ้มครองข้อมูลของรัฐสมาชิกอื่นๆ

โครงสร้างและความเป็นอิสระของหน่วยงานคุ้มครองข้อมูล
  • ความเป็นอิสระของหน่วยงานคุ้มครองข้อมูลเป็นปัจจัยที่ขาดไม่ได้ในการที่จะรับประกันว่าจะมีการคุ้มครองข้อมูลเป็นอย่างดี
  • ด้วยเหตุนี้ มาตรการในเชิงโครงสร้างสถาบัน เช่น การกำหนดลักษณะทางนิติบุคคลเป็นพิเศษสำหรับหน่วยงานกำกับดูแลข้อมูล (เช่นในสเปนและมอลตา) หรือการระบุลงไปในรัฐธรรมนูญถึงอำนาจและหน้าที่ (เช่นในรัฐธรรมนูญของโปรตุเกสและกรีซ) เป็นตัวอย่างที่ดีที่จะเพิ่มความเป็นอิสระของหน่วยงานกำกับดูแล
  • แม้การเลือกตั้งคณะกรรมการหรือผู้บริหารหน่วยงานคุ้มครองข้อมูล โดยฝ่ายนิติบัญญัติ (เช่นในเยอรมนีและในสโลเวเนีย) จะไม่ได้รับประกันเสมอไปว่าเจ้าหน้าที่หน่วยงานคุ้มครองจะมีความเป็นอิสระ แต่กระบวนการที่จำเป็นต้องให้มีฉันทามติระหว่างสมาชิกสภานิติบัญญัติเสียงข้างมากและฝ่ายค้าน (เช่นในกรีก) ก็ควรได้รับการพิจารณาว่าเป็นวิธีปฏิบัติที่ดีที่สุด
  • รัฐสมาชิกบางแห่งได้ออกแบบมาตรการลดอิทธิพลและแรงกดดันทางการเมือง เพื่อเป็นการรับประกันความเป็นอิสระของหน่วยงานคุ้มครองข้อมูล เช่นการกำหนดให้เจ้าหน้าที่ของหน่วยงานจะพ้นตำแหน่งก่อนกำหนดวาระได้ก็ต่อเมื่อประพฤติขัดกับหลักการที่ได้ระบุไว้ล่วงหน้า และก็ต่อเมื่อได้ผ่านกระบวนการเช่นเดียวกับที่ใช้ในตอนแต่งตั้งเท่านั้น (เช่นในสโลเวเนีย โปแลนด์)
อำนาจในการกำหนดระเบียบปฏิบัติของหน่วยงานคุ้มครองข้อมูล
  • วิธีปฏิบัติที่ดีที่สุดอีกอย่างหนึ่ง ที่จะรับประกันความเป็นอิสระของหน่วยงานคุ้มครองข้อมูล คือการที่หน่วยงานคุ้มครองข้อมูลมีสิทธิที่จะนำกฎหมายเข้าสู่ศาลรัฐธรรมนูญ เพื่อให้ศาลพิจารณาว่ากฎหมายดังกล่าวชอบด้วยรัฐธรรมนูญหรือไม่ (เช่นในสโลเวเนีย)
  • อำนาจของหน่วยงานคุ้มครองข้อมูลที่จะจัดเตรียมระเบียบปฏิบัติ (code of conduct) ก็เป็นวิธีปฏิบัติที่ดีเช่นกัน การมีส่วนร่วมในการร่างระเบียบปฏิบัติในการคุ้มครองข้อมูลนั้นไม่เพียงเพิ่มการคุ้มครองข้อมูลสำหรับประชาชน แต่ยังช่วยให้หน่วยงานคุ้มครองข้อมูลเป็นที่รู้จักและถูกมองเห็นในสังคม และหน่วยงานคุ้มครองข้อมูลควรเข้าร่วมกระบวนการนี้ในเชิงรุกอย่างแข็งขัน
  • ในไอร์แลนด์ กฎหมายมอบอำนาจให้กับหน่วยงานคุ้มครองข้อมูลส่วนบุคคลแห่งชาติในการเสนอและจัดเตรียมระเบียบปฏิบัติ ซึ่งถ้าหากได้รับความเห็นชอบจากฝ่ายนิติบัญญัติ ก็จะมีผลบังคับตามกฎหมาย (Ireland Data Protection Act [1988-2003], Section 13)
ทรัพยากร
  • นอกเหนือจากความเป็นอิสระและอำนาจที่จำเป็น หน่วยงานคุ้มครองข้อมูลจำเป็นต้องได้รับประกันว่าจะได้รับทรัพยากรมนุษย์และทรัพยากรทางการเงินที่จำเป็นอย่างเพียงพอ เพื่อให้สามารถบังคับใช้ระบบการคุ้มครองข้อมูลได้อย่างมีประสิทธิภาพ
  • ในรัฐสมาชิกส่วนใหญ่ หน่วยงานคุ้มครองข้อมูลได้รับการสนับสนุนทรัพยากรที่จำเป็นจากงบประมาณของรัฐ (เช่นในอิตาลี ฝรั่งเศส เนเธอร์แลนด์ และเอสโตเนีย) ซึ่งโดยมากจะอยู่ในงบประมาณกระทรวงยุติธรรม
  • อย่างไรก็ตาม ในบางรัฐสมาชิก หน่วยงานคุ้มครองก็สามารถหาทรัพยากรทางการเงินเพิ่มเติมได้อย่างมีนัยสำคัญ จากรายได้ที่ได้มาจากค่าแจ้งเตือนผู้ประมวลผลข้อมูล และ/หรือ จากค่าปรับที่เป็นตัวเงินที่มาจากการลงโทษการละเมิดกฎหมายคุ้มครองข้อมูล (เช่นในลักเซมเบิร์กและมอลตา)
ความร่วมมือระหว่างหน่วยงาน
  • ความร่วมมือและการสื่อสารอย่างสม่ำเสมอระหว่างหน่วยงานรัฐและหน่วยงานคุ้มครองข้อมูลจะทำให้ระบบการคุ้มครองข้อมูลโดยรวมทำงานอย่างราบรื่นยิ่งขึ้น
  • ในเยอรมนี โครงการอบรมขนาดใหญ่ดำเนินงานในรูปแบบโรงเรียนคุ้มครองข้อมูล ซึ่งได้พัฒนาหลักสูตรอบรมที่ครอบคลุมและเป็นระบบ สำหรับการบริหารงานปกครองในทุกด้าน
  • ความร่วมมือและการสื่อสารอย่างใกล้ชิดกับหน่วยงานที่ไม่ใช่รัฐ (เอ็นจีโอ) ที่ทำงานในด้านนี้ มีประโยชน์หลายประการ
  • ประการแรกคือ หน่วยงานที่ไม่ใช่รัฐหรือเอ็นจีโอนั้นอยู่ในฐานะที่จะสามารถส่งสัญญาณว่ามีการละเมิดกฎหมายคุ้มครองข้อมูลที่ชัดเจนหรืออย่างเป็นระบบ ให้หน่วยงานคุ้มครองข้อมูลหรือให้กับประชาสังคมได้รับทราบ ซึ่งเท่ากับว่าเราจะมีหน่วยงานกำกับดูแลที่ไม่ใช่รัฐเพิ่มเติมขึ้นมา ซึ่งในหลายกรณี การมีหน่วยงานที่ไม่ใช่รัฐเพิ่มขึ้นมานี้ ก็ช่วยให้การตรวจตราการคุ้มครองข้อมูลเป็นไปได้ครอบคลุมมากขึ้น
  • ประการที่สอง เอ็นจีโอนั้นทำให้มีช่องทางสื่อสาร ‘จากล่างขึ้นบน’ ซึ่งทำให้พลเมืองมีโอกาสที่จะเสนอการแก้ไขปรับปรุงกรอบกฎหมาย
    • จากมุมมองนี้ หน่วยงานคุ้มครองข้อมูลของฮังการีได้ช่วยเหลือและร่วมมือกับเอ็นจีโอหลายแห่ง ตัวอย่างเช่น ในปี 2000 หน่วยงานคุ้มครองข้อมูลได้ทบทวนแผนงานคุ้มครองข้อมูลสำหรับโครงการวิจัยสิทธิของชาวโรมา (ยิปซี) ซึ่งดำเนินงานโดยคณะกรรมการเฮลซิงกิฮังการี และในปี 2004 เจ้าหน้าที่ของหน่วยงานได้ร่วมกับสหภาพสิทธิพลเมืองฮังการีทำการทดสอบสถานพยาบาลจำนวนหนึ่งเพื่อดูว่าการตรวจเชื้อเฮชไอวีนั้นได้ทำไปอย่างเป็นนิรนามและไม่มีค่าใช้จ่ายจริงอย่างที่ได้ประกาศหรือไม่ และหลังจากนั้นก็ได้ออกข้อแนะนำซึ่งตั้งอยู่บนฐานของข้อค้นพบระหว่างการทดสอบดังกล่าว
  • ประการสุดท้าย ความร่วมมือและการสื่อสารอย่างสม่ำเสมอระหว่างหน่วยงานคุ้มครองข้อมูลของรัฐอื่นๆ ทั้งในและนอกสหภาพยุโรป ก็เป็นประโยชน์เช่นกัน
    • ในระดับสหภาพยุโรป สิ่งนี้ถูกทำให้เป็นจริงหลักๆ ผ่านทางคณะทำงานซึ่งก่อตั้งตามมาตรา 29 ของ Data Protection Directive เวทีนี้ทำให้มีสภาพแวดล้อมเชิงสถาบันที่จำเป็น เพื่อให้หน่วยงานคุ้มครองข้อมูลจากรัฐต่างๆ สามารถปรับประสานการใช้กฎหมายของตัวเองให้สอดคล้องเข้ากันได้กับรัฐอื่นๆ
    • ความร่วมมือแบบทวิภาคีและพหุภาคีก็เป็นเรื่องที่ควรส่งเสริมให้เกิด ทั้งในภายในสหภาพยุโรปและกับประเทศนอกสหภาพยุโรป ตัวอย่างที่ดีเช่นการที่โปรตุเกสกับสเปนมีการประชุมอย่างไม่เป็นทางการร่วมกันเป็นประจำทุกปี เพื่อพูดคุยเกี่ยวกับพัฒนาการที่สำคัญในการคุ้มครองข้อมูล

 

เรื่องที่เกี่ยวข้อง: ออกแบบอำนาจ: อ่านโครงสร้างคณะกรรมการในกฎหมายไทย

LookHin: เขียนโปรแกรมอัพโหลดข้อมูลไปเก็บไว้ที่ Google Drive

17 March, 2017 - 18:07

พอดีผมทำ Google Drive API และเอาขึ้น Github เอาไว้ โดยสามารถดาวน์โหลดได้จาก Google Drive API บทความนี้จะเขียนอธิบายวิธีใช้นิดหน่อย จุดประสงค์ของการทำ API ชุดนี้ก็เพื่อจะทำโปรแกรมสำหรับอัพโหลดไฟล์จาก server ไปเก็บไว้ยัง Google Drive โดยอัตโนมัติ เพื่อทำการ backup ข้อมูล โดยใน API สามารถที่จะแสดงรายชื่อไฟล์และโฟลเดอร์, สร้างโฟลเดอร์ใหม่, ลบไฟล์และโฟลเดอร์ และอัพโหลดไฟล์เข้าไปยังโฟลเดอร์ที่กำหนดไว้ได้ หากใครต้องการเพิ่มความสามารถอื่นเข้าไป ก็สามารถอ่านวิธีเรียกใช้งาน API ได้จาก Reference ด้านล่างบทความนะครับ

ในการเรียกใช้งาน Service ของ Google API เราต้องทำการร้องขอ Access Token ไปยัง Server ของทาง Google เพื่ออนุญาตให้แอพที่เราสร้างสามารถเข้าถึง Service ที่เราระบุเอาไว้ได้ ซึ่งเมื่อเราได้ Access Token มาแล้วเราสามารถที่จะใช้ Access Token ตัวนี้ในการเรียกใช้ API ต่างๆ ได้ ซึ่งในบทความนี้เราจะทำการเรียกใช้ Google Drive API

มาลองทดลองทำจริงเลยดีกว่าครับ เริ่มแรกเลยให้ทำการดาวน์โหลดโค้ดทั้งหมดจาก Github ลงมาก่อน https://github.com/LookHin/google-drive-api จากนั้นทำการเปิดใช้งาน Google Drive API โดยคลิกเข้าไปที่ Enable Google Drive API จากนั้นเลือกสร้างโปรเจคใหม่ หรือเลือกโปรเจคเก่าที่เรามีอยู่แล้วก็ได้

คลิก Create credentials และเลือก OAuth client ID

ในช่อง Application type ให้เลือกเป็น Other และช่อง Name ให้ใส่เป็นชื่อที่เราต้องการ และคลิก Create

หลังจากคลิก Create แล้วระบบจะแสดง Client Id และ Client secret ขึ้นมาให้ ให้เรา copy รหัสทั้ง 2 ตัวนี้ไปใส่ในไฟล์ authorize.php และ example.php

$strClientId = "YOUR_CLIENT_ID";
$strClientSecret = "YOUR_CLIENT_SECRET";

ทำการ Authorize โดยเรียก authorize.php จากบราวเซอร์ เช่น http://YOUR_SERVER/google-drive/authorize.php และทำการคลิก Allow เพื่อทำการอนุญาติให้แอพที่เราสร้างสามารถเข้าถึงข้อมูลใน Google Drive ได้

หลังจากคลิก Allow แล้วระบบจะแสดง Refresh Token ขึ้นมาให้ ให้ทำการ copy รหัสตัวนี้ไปใส่ในไฟล์ example.php

$strRefreshToken = "YOUR_REFRESH_TOKEN";

เพียงเท่านี้โปรแกรมของเรา ที่เราเขียนไว้ในไฟล์ example.php ก็พร้อมที่จะทำงานได้แล้วครับ แต่ก่อนอื่นมารู้จักกับ File Id และ Folder Id ที่ใช้ภายใน Google Drive กันก่อน ในระบบของ Google Drive จะอ้างอิงถึงไฟล์และโฟลเดอร์ต่างๆ ผ่านทาง Id ฉะนั้นเวลาเราจะสร้างโฟลเดอร์ใหม่ หรือทำการอัพโหลดเข้าไปในโฟลเดอร์ต่างๆ เราต้องรู้ก่อนว่าโฟลเดอร์นั้นมี Id เป็นอะไร โดยวิธีที่ง่ายที่สุดก็คือเปิดเข้าไปที่ Google Drive และคลิกเลือกไปที่โฟลเดอร์ที่ต้องการ เราจะเห็น Id ของโฟลเดอร์นั้นๆ แสดงเป็น URL ดังรูป

ตัวอย่าง: จากตัวอย่างของโค้ด ผมทำตัวอย่างการแสดงไฟล์ สร้างโฟลเดอร์ ลบไฟล์และโฟลเดอร์ และอัพโหลดไฟล์ไว้ให้แล้ว ลองเล่นกันดูครับ

setAccessTokenFromRefreshToken($strRefreshToken);

// List File From Root Folder
$arrFile = $obj->ListFileAndFolder("root");
print_r($arrFile);

// # List File From Folder Id
//$arrFile = $obj->ListFileAndFolder("_PARENT_FOLDER_ID_");
//print_r($arrFile);

// # Create Folder In Root Folder
//$obj->CreateFolder("root", "_NEW_FOLDER_NAME_");

// # Create Folder In Parent Folder
//$obj->CreateFolder("_PARENT_FOLDER_ID_", "_NEW_FOLDER_NAME_");

// # Delete File & Folder
//$obj->Delete("_FILE_OR_FOLDER_ID_");

// # Upload File To Root Folder
// $arrResult = $obj->Upload("root", "no-face.png");
// print_r($arrResult);

// # Upload File To Parent Folder
// $arrResult = $obj->Upload("_PARENT_FOLDER_ID_", "no-face.png");
// print_r($arrResult);

?>

อ้างอิง :
https://github.com/LookHin/google-drive-api
https://developers.google.com/identity/protocols/OAuth2WebServer
https://developers.google.com/drive/v3/reference/files
https://developers.google.com/drive/v3/web/resumable-upload

Kitt: Google Cloud Platform Free Tier

12 March, 2017 - 16:04
Google recently provide the free tier on their Google Cloud Platform (GCP). The free tier will be free forever (but what Google offered are subjected to changes). Also included in the free tier is $300 credit for 12 months (I think this was 2 months – good !) I applied, created Google Compute Engine (GCE) f1-micro instance, … Continue reading Google Cloud Platform Free Tier →

Kitt: Yet another leap second added

12 March, 2017 - 15:33
235960 – 23:59:60 – the leap second added. UTC (based on solar mean)  – TAI (based on atomic clock) = -37 seconds Happy New Year 2017 UTC

Kitt: กบ CoE #2

10 March, 2017 - 13:28
ผมกับกบ CoE#2 สนิทกันประมาณนึง ด้วยกบจบจากสาธิตมอดินแดง เป็นพี่โรงเรียนเดียวกับส้ม กบจะเรียกผมว่าพี่เสมอ ไม่เคยเรียกผมว่าอาจารย์ กบชอบเล่นเกม โค้ดเก่ง คิดเก่ง พลิกแพลงเก่ง แต่ .. เรียนไม่เก่ง กบใช้เวลาเรียนหลายปีกว่าจะจบด้วยเกรด 2.0 กว่า ๆ ด้วยความที่เรียนนาน เข้าคลาสเรียนกับน้อง ๆ เลยเป็นที่รู้จักของน้อง ๆ รุ่นหลังอีกหลายรุ่น ถ้าจำไม่ผิดคน กบเข้าไปทำงานแรก ๆ ทำงานได้ดีโดยเจ้านายไม่รู้ว่าเกรดมันห่วย วันที่เจ้านายรู้ว่ากบจบด้วยเกรดห่วย ๆ จึงเกิดประโยคที่ว่า “มี วศ.คอม.มข. เกรด 2.0 แบบคุณอีกไหม ?” ผมเจอกบครั้งสุดท้ายหลายปีก่อน กบแวะมาที่ภาคฯ ถือเกมมาให้เล่น ก็ยังได้มานั่งเล่นเกมกันเหมือนสมัยอยู่ห้องโปรเจค ตัดมาอีกทีก็มารู้ข่าวเรื่องอาการเนื้องอกในสมองของกบ ช่วงปลายมกราฯ ที่ผ่านมา กบอาการทรุดลงไปอีก เพื่อน ๆ น้อง ๆ บางคนพอทราบก็ไปเยี่ยม/นัดกันว่าจะไปเยี่ยมที่บ้าน เมื่อวาน น้องไปสบายแล้ว ใจหายว่ะ

Kitt: Vultr’s $2.5 / month server instance

10 March, 2017 - 13:22
Vultr has recently upgrade all instances . While $5/month has been upgraded from 1 CPU / 768 MB / 15 GB  to 1 CPU / 1 GB / 25 GB, Vultr also introduced the new smallest server instance – 1 CPU / 512 MB / 20 GB at $2.5/month. So, I have choices:  keep paying $5/month … Continue reading Vultr’s $2.5 / month server instance →

LookHin: การสร้าง LINE Bot ด้วย Line Messaging API (Official API)

6 March, 2017 - 20:31

ก่อนหน้านี้ผมเคยลองทำ LINE Bot เล่นบ้างอยู่เหมือนกัน แต่ตอนนั้น LINE เขายังไม่มี Official API ออกมาให้ ทำให้เราต้องแอบเล่นผ่าน Unofficial API ที่มีคนแกะออกมาจากตัวโปรแกรมของไลน์อีกที ข้อดีคือมันใช้กับ Account ธรรมดาของเราได้ แต่ด้วยความที่มันไม่ใช่ Official API ก็ไม่มีอะไรการันตีให้เราได้ว่ามันจะทำงานสมบูรณ์ หลังๆ มานี้ LINE เขาเอาใจ Developer มากขึ้น เขามี Official API ออกมาให้ใช้งานแล้ว แต่ว่าจะใช้งานกับ Account ธรรมดาไม่ได้ ต้องใช้กับ account ที่เป็น LINE@ เท่านั้น ซึ่งเราสมัครใช้งานได้ฟรีๆ อยู่แล้ว

โดยระบบที่เราจะทดสอบทำกันวันนี้ จะเป็นการรอรับข้อความจากผู้ใช้และตอบกลับข้อความนั้นๆ ด้วยข้อความที่เราเตรียมไว้ และทำการส่งข้อความหาผู้ใช้ที่แอ็ดเป็นเพือนกับบอทของเราเพื่อใช้สำหรับสร้างระบบแจ้งเตือนต่างๆ เช่นแจ้งผู้บุกรุก แจ้งราคาน้ำมัน แจ้งราคาทองอะไรประมาณนั้น

มาเริ่มกันเลย ในการสร้าง LINE Bot ให้เราล๊อกอินเข้าไปที่ LINE Business Center และทำการกรอกข้อมูลและลงทะเบียนให้เรียบร้อย อันนี้ทำเองนะครับ พอดีผมไม่ได้ print screen หน้าจอเอาไว้ เข้าไปทำอีกรอบไม่ได้ ฮาาา

เมื่อลงทะเบียนเสร็จแล้วให้เข้าไปที่เมนู Service -› Messaging API และคลิกที่ปุ่ม Start using Developer Trial

ทำการตั้งชื่อบอท เลือกรูปภาพ และกรอกข้อมูลอื่นๆ ให้เรียบร้อย จากนั้นกดปุ่ม OK ด้านล่าง

ตรวจสอบข้อมูลต่างๆ ให้เรียบร้อยแล้วกด Apply

เมื่อสร้างเรียบร้อยแล้วให้คลิกที่ LINE@ Manager

จากนั้นกดที่ปุ่ม “ใช้ API” และกด “ยืนยัน” (อ้าว ภาษาไทยได้ไงหว่า)

จะเห็นว่าตอนนี้เราสามารถใช้งาน API ได้ 2 ฟังชั่นคือ REPLY_MESSAGE และ PUSH_MESSAGE โดยสามารถดูรายละเอียดการใช้งานทั้ง 2 ฟังชั่นนี้ได้จาก REPLY_MESSAGE และ PUSH_MESSAGE คลิกเข้าไปดูจะเห็นว่าเขียนไม่ยากครับ แค่รอรับและส่งข้อมูลกลับไปกลับมาเท่านั้น

ในหน้านี้จะเห็นว่าด้านขวามือมีชื่อของบอทขิงเราอยู่ พร้อมกับ LINE@ ID ของบอท เราสามารถแอ็ดเฟรนจาก ID นี้เลยก็ได้ หรือจะใช้ QR Code ในขั้นตอนถัดไปก็ได้ครับ และในส่วนของการตั้งค่าให้เลือก webhook เป็น “อนุญาต” และเลือก Bot เข้าร่วมกลุ่มแชท, ข้อความตอบรับอัตโนมัติ, คำทักทายเริ่มต้นสำหรับการเพิ่มเพื่อนใหม่ เป็น “ไม่อนุญาต” ทั้งหมด แต่ถ้าหากใครจะลองเปิดไว้ก็ได้นะครับ ทาง LINE เขามีระบบตอบรับข้อความอัตโนมัตไว้ให้อยู่แล้ว แทบไม่ต้องทำอะไรเพิ่มเลย เมื่อเลือกเสร็จแล้วกด “บันทึก” เมื่อกดบันทึกเรียบร้อยแล้วให้กดที่ LINE Developers ต่อได้เลยครับ เดียวเราต้องไปใส่ URL ของ webhook ในหน้านั้นอีกที

ในหน้านี้จะเห็นว่ามี QR Code เราสามารถใช้ QR Code ตัวนี้เพื่อทำการแอ็ดเฟรนกับบอทได้เลยครับ หรือจะแอ็ดโดยใช้ LINE@ ID จากหน้าที่แล้วก็ได้ แต่ ID มันสุ่มมาให้อาจจะพิมพ์ตามยากหน่อย และในหน้าเดียวกันจะเห็นว่าในช่อง Webhook URL ยังไม่มีค่าอะไร ให้กด Edit

ทำการใส่ Webhook URL ของเราลงไปครับ URL ตรงนี้จะเป็น URL ที่ใช้รับข้อความจาก LINE โดยจะต้องเป็น HTTPS เท่านั้นนะครับ

หลังจากที่เราใส่ Webhook URL เข้าไปแล้ว ขั้นตอนถัดไปเป็นขั้นตอนการหา Access Token เพื่อเอาไปใช้กับโปรแรกมของเรา ให้คลิกเข้าไปที่ ISSUE ระบบก็จะแสดง Access Token ขึ้นมาให้

เอาหละ เกือบเสร็จแล้ว ขั้นตอนถัดไปคือการเขียนโปรแกรมครับ copy โค้ดตามนี้และทำความเข้าใจกันเอาเองอธิบายไม่ถูกหละ โดยโค้ดชุดนี้จะเป็นการรอรับข้อความที่ถูกส่งเข้ามา และเราจะตอบกลับข้อความนั้นกลับไปว่า ID ของเขาชื่ออะไร หรือหากว่าใครจะเพิ่มคำสั่งอื่นลงไปก็เพิ่มเข้าไปเองเลยครับ และเราจะต้องใช้ ID ตัวนี้ในการส่งข้อความแจ้งเตือนโดยไม่ต้องรอให้ผู้ใช้ทักเข้ามาด้วย (ดูโค้ดแล้วทำการแก้ไข ACCESS_TOKEN เป็น Token ของตัวเองให้เรียบร้อยนะครับ)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
 
$strAccessToken = "ACCESS_TOKEN";
 
$content = file_get_contents('php://input');
$arrJson = json_decode($content, true);
 
$strUrl = "https://api.line.me/v2/bot/message/reply";
 
$arrHeader = array();
$arrHeader[] = "Content-Type: application/json";
$arrHeader[] = "Authorization: Bearer {$strAccessToken}";
 
if($arrJson['events'][0]['message']['text'] == "สวัสดี"){
  $arrPostData = array();
  $arrPostData['replyToken'] = $arrJson['events'][0]['replyToken'];
  $arrPostData['messages'][0]['type'] = "text";
  $arrPostData['messages'][0]['text'] = "สวัสดี ID คุณคือ ".$arrJson['events'][0]['source']['userId'];
}else if($arrJson['events'][0]['message']['text'] == "ชื่ออะไร"){
  $arrPostData = array();
  $arrPostData['replyToken'] = $arrJson['events'][0]['replyToken'];
  $arrPostData['messages'][0]['type'] = "text";
  $arrPostData['messages'][0]['text'] = "ฉันยังไม่มีชื่อนะ";
}else if($arrJson['events'][0]['message']['text'] == "ทำอะไรได้บ้าง"){
  $arrPostData = array();
  $arrPostData['replyToken'] = $arrJson['events'][0]['replyToken'];
  $arrPostData['messages'][0]['type'] = "text";
  $arrPostData['messages'][0]['text'] = "ฉันทำอะไรไม่ได้เลย คุณต้องสอนฉันอีกเยอะ";
}else{
  $arrPostData = array();
  $arrPostData['replyToken'] = $arrJson['events'][0]['replyToken'];
  $arrPostData['messages'][0]['type'] = "text";
  $arrPostData['messages'][0]['text'] = "ฉันไม่เข้าใจคำสั่ง";
}
 
 
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$strUrl);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $arrHeader);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($arrPostData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close ($ch);
 
?>

หลังจากเขียนโค้ดและอัพโหลดขึ้นเซิฟเวอร์เรียบร้อยก็ลองทักบอทของเราได้เลยครับ มันตอบคำถามได้บ้างหละ

ขึ้นตอนถัดไปเราจะทำระบบ Push message ฟังชั่นนี้เอาไว้ทำระบบแจ้งเตือนต่างๆ เช่นการแจ้งเตื่อนผู้บุกรุกจากอุปกรณ์ IoT หรือแจ้งเตือนราคาน้ำมัน ราคาทองอะไรก็แล้วแต่ โดยเราต้องใช้ ID ของผู้รับจากขั้นตอนที่แล้วในการส่ง เราอาจจะเก็บ User ID ลง Databsae เพื่อเอามาไว้ใช้ทีหลังอะไรก็แล้วแต่นะครับ แต่สำหรับโค้ดตัวอย่างนี้ผมจะใส่ User Id ลงไปตรงๆ (แก้ ACCESS_TOKEN และ USER_ID ให้เรียบร้อยและลองรันได้เลยครับ)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
 
$strAccessToken = "ACCESS_TOKEN";
 
$strUrl = "https://api.line.me/v2/bot/message/push";
 
$arrHeader = array();
$arrHeader[] = "Content-Type: application/json";
$arrHeader[] = "Authorization: Bearer {$strAccessToken}";
 
$arrPostData = array();
$arrPostData['to'] = "USER_ID";
$arrPostData['messages'][0]['type'] = "text";
$arrPostData['messages'][0]['text'] = "นี้คือการทดสอบ Push Message";
 
 
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$strUrl);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $arrHeader);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($arrPostData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close ($ch);
 
?>

หลังจากตรงนี้ไป ก็ไปต่อยอดกันเอาเองครับ แล้วแต่จินตนาการกันเช่นเคย

อ้างอิง :
https://developers.line.me/messaging-api/getting-started
https://devdocs.line.me/en/

Kitt: Tokyo Marathon 2017

1 March, 2017 - 17:26
การท่องเที่ยวแห่งประเทศไทย พาผู้จัดงานมาราธอนในเมืองไทยไปร่วมงาน Tokyo Marathon Expo 2017 ที่ญี่ปุ่นเพื่อช่วยประชาสัมพันธ์เชิญชวนนักวิ่งญี่ปุ่นและต่างชาติไปวิ่งที่ประเทศไทย โดยนำผู้จัด Khon Kaen International Marathon, Chiang Mai, Laguna Phuket, Pattaya, BDMS Bangkok, Amari Charity ไปร่วมงาน ระหว่างวันที่ 23 – 26 กุมภาพันธ์ 2017 Tokyo Marathon เป็นหนึ่งในหก World Majors (Berlin, Boston, Chicago, London, New York, Tokyo) ของมาราธอน เป็นรายการที่จะได้วิ่งแข่งกับนักวิ่งระดับโลกที่แข่งกันในรายการ IAAF Championship หรือ Olympic และเป็นรายการเดียวที่จัดในเอเชีย รวมถึงเป็นรายการคัดตัวเพื่อไปวิ่งรายการใหญ่ ๆ ของญี่ปุ่นและของโลก Tokyo Marathon จัดพื้นที่วิ่งไว้ 35,500 ที่สำหรับระยะ … Continue reading Tokyo Marathon 2017 →

Neutron: rlm_raw - FreeRADIUS module

24 February, 2017 - 14:59

เรื่องนี้ เกี่ยวข้องกับ FreeRADIUS [1] ซึ่งคนที่เคยติดตั้ง และใช้งาน จะรู้ว่า FreeRADIUS จะมีฝั่ง Server และ Client โดยทั้งสองฝั่งจะถือ กุญแจ (Shared Secret) เดียวกัน โดยที่ Server จะใช้ IP Address ของ Client ในการเลือก กุญแจ ออกมาเทียบ

ปัญหาที่เกิดขึ้นคือ การใช้ FreeRADIUS เป็น Server ให้กับ Client ที่มี IP ไม่แน่นอน อย่างเช่น พวกที่มาจาก xDSL, FTTx เราจะไม่สามารถกำหนด Shared Secret ให้กับ Client นั้น ๆ ได้ นอกจากทุก Client จะถือกุญแจเดียวกัน ร่วมกันหลาย ๆ ราย

การใช้กุญแจร่วมกัน ก็อาจจะเป็นทางออก แต่ผมหาข้อมูลไปต่อ ว่าพอจะมีวิธีอื่น ๆ ที่รัดกุมกว่านี้ไหม ก็ไปเจอ [2] ที่พูดถึง rlm_raw และ dynamic_clients ซึ่งเราสามารถที่จะเอาข้อมูลจาก attribute ที่ client ส่งมา เพื่อไปใช้ประกอบกับการเลือก กุญแจ ออกมาเทียบได้ แต่ทว่า rlm_raw (original) ค่อนข้างเก่า และดึงมาใช้ตรง ๆ กับ FreeRADIUS 3.0.x ไม่ได้

ผมจึงเขียน rlm_raw [3] ขึ้นมาใหม่ โดยดู original เป็นแนวทาง และปรับมาใช้ libradius ซึ่งทำให้ code ที่เขียนใหม่ สะอาด และกระชับ กว่า code เดิมมาก

จาก ตัวอย่าง ใน README จะเห็นได้ว่า ผมสามารถ ที่จะใช้ค่า จาก attribute "NAS-Identifier" เพื่อไปเลือก secret ออกมาจาก redis server เพื่อมาตั้งค่า Client ใหม่ให้ FreeRADIUS ได้

Happy Hacking!

[1] http://freeradius.org/
[2] http://jakehe.blogspot.com/2014/07/freeradius-installation.html
[3] https://github.com/neutronth/rlm_raw

LookHin: การดักจับข้อมูลที่วิ่งเข้าออกบน HTTP/HTTPS จากแอพในมือถือ Android โดยใช้ Burp Suite

22 February, 2017 - 22:14

บทความนี้จะแสดงตัวอย่างการดักจับข้อมูลจากแอพในมือถือ Android ที่รับส่งไปยังเซิฟเวอร์ทั้งบน HTTP และ HTTPS โดยเราจะทดสอบกับแอพของไปรษณีย์ที่ใช้สำหรับตรวจสอบสถานะการส่งพัสดุ Thailand Post Track & Trace เพื่อให้เห็นว่ามีการส่งข้อมูลอะไรออกไปที่เซิฟเวอร์บ้าง โดยในการทดลองนี้จะทำกับแอพที่ใช้ certificate ของระบบเท่านั้น ส่วนแอพอย่างของ facebook หรือ instagram เขาจะมี certificate ของตัวเองที่ฝั่งมากับแอพทำให้เราไม่สามารถหลอกโปรแกรมได้ หรืออาจจะยืนยัน CA ว่าเป็น CA จริงหรือไม่ผ่านทาง DNS อีกที (ผมเข้าใจว่าอย่างนั้นนะ อันนี้ไม่แน่ใจ เดียวผมไปหาข้อมูลเพิ่มเติมมาก่อน)

ในการทดลองการดักจับข้อมูลครั้งนี้ เราจะให้ทั้งคอมฯ และมือถือต่ออยู่ใน Wi-Fi เน็ทเวิร์คเดียวกัน โดยเราจะใช้ Burp Suite Free Edition ซึ่งสามารถหาดาวน์โหลดได้จาก Burp Suite Free Edition เป็นโปรแกรมที่ทำหน้าที่เป็น proxy แต่ผมไม่ลงวิธีการติดตั้งนะครับตัวใครตัวมัน

หลังจากติดตั้งเรียบร้อยแล้ว ให้เปิดโปรแกรม Burp Suite Free Edition และเข้าไปที่แท็บ Proxy -› Options และเลือก Add เพื่อตั้ง proxy ใหม่

ทำการกำหนด Bind to port เป็น 8089 (ปกติก็คงเป็น 8080 แต่พอดีผมใช้มันไปทำอย่างอื่นแล้ว) และเลือก Bind to address เป็น All interfaces เมื่อใส่ค่าทุกอย่างเรียบร้อยก็คลิก OK

Windows Firewall จะขึ้นมาถามยืนยันการใช้งานพอร์ทให้กด Allow access

ถ้าในช่อง Running ในส่วนของ proxy ที่เราสร้างไว้ยังไม่ถูกติ๊กเป็นเครื่องหมายถูก ก็ติ๊กให้มันทำงานด้วยครับ

และในแท็บ Intercept ให้เลือก Intercept เป็น Off

จากนั้นมาที่มือถือ Android โดยให้เข้าไปที่ Setting -› Wi-Fi กดค้างที่ Wi-Fi ที่เราต่อเอาไว้แล้วเลือก Modify network

เลือก Show Advanceed options ติ๊กเลือก Show advance options และเลือก Proxy เป็น Manual และใส่ค่าต่างๆ ดังนี้

Proxy hostname = ให้ใส่ IP ของเครื่องคอมฯ ที่เราติดตั้ง Burp Suite ไว้
Proxy port = ใส่หมายเลข port ที่เรากำหนดไว้ใน Burp Suite

จากนั้นกด Connect

ขั้นตอนถัดไปคือการติดตั้ง CA Certificate ของ Burp Suite ลงในเครื่อง Android ให้เราพิมพ์ URL http://burp บนบราวเซอร์ของ Android และคลิกที่ปุ่ม CA Certificate เพื่อทำการดาวน์โหลด เมื่อทำการดาวน์โหลดมาแล้วจะได้ไฟล์ชื่อ cacert.der ให้ทำการเปลี่ยนนามสกุลของไฟล์เป็น cacert.cer

ทำการติดตั้ง CA Certificate โดยเข้าไปที่ Setting -› Advanced settings -› Security และเลือก Install from SD card

เลืกไฟล์ cacert.cer และทำการตั้งชื่อ Cartificate name

ที่หน้า Setting -› Advanced settings -› Security คลิกที่แท็บ Trusted credentials และเลือกแท็บ User จะเห็นว่ามี CA Certificate ใหม่ของเราติดตั้งไว้แล้ว เป็นอันเสร็จเรียบร้อย

ต่อไปมาเริ่มทำการทดสอบกันเลยครับ ว่ามันสามารถดักข้อมูลที่วิ่งผ่าน HTTP/HTTPS ได้จริงไหม โดยให้เปิดบราวเซอร์และพิมพ์ url ที่เป็น HTTPS ลงไป ในตัวอย่างก็เทสจากเว็บผมเองนี้หละ จะเห็นว่า HTTPS ก็ยังเป็นสีเขียวอยู่

กลับมาดูที่หน้า Burp Suite ในแท็บ HTTP history จะเห็นว่ามีข้อมูลที่วิ่งไปยังเว็บของเราแล้ว

ทีนี้ลองเปิดแอพบน Android ขึ้นมาครับ ตัวอย่างนี้ผมเลือกใช้แอพของไปรษณีย์เพราะอยากรู้ว่าเขาส่งข้อมูลไปตรวจสอบสถานะของพัสดุที่ไหน โดยลองกรอกรหัสที่ใช้ตรวจสอบพัสดุ EMS ลงไปดูนะครับ หรือหากใครจะลองแอพตัวอื่นก็ได้เช่นกัน เอาจากของไทยๆก่อนนี้หละครับ ง่ายดี

กลับมาดูที่หน้า HTTP history จะเห็นว่ามีข้อมูลวิ่งที่ยังเซิฟเวอร์ของไปรษณีย์ไทยแล้วครับ (อ้าว มี username กับ password ติดมาด้วย อันนี้ไม่ได้ตั้งใจ อยู่นอกเหนือจากที่ผมคิดไว้ ฮาาา)

Kitt: CPU overloaded by kidle_inject ?

21 February, 2017 - 04:42
As it’s named, kidle_inject is a process to inject idleness to processors. On a good day, this will keep idle your processors, lower processor temperature, and save your battery. On a bad day, it will consume your processor somewhat like 50%+ on all cores, slow down your laptop, and drain your battery. But, you can … Continue reading CPU overloaded by kidle_inject ? →

LookHin: การดาวน์โหลดวิดีโอจาก youtube, udemy, facebook โดยใช้ youtube-dl และ ffmpeg

14 February, 2017 - 19:18

เรื่องนี้สุ่มเสี่ยงที่จะผิดกฏหมาย ถึงแม้จะนำมาใช้งานส่วนตัวผมก็ไม่แน่ใจนัก แต่อย่างน้อยเรามาตกลงกันก่อนว่าเราจะดาวน์โหลดแค่งานที่เป็นสาธารณะ และศึกษาการใช้งานทูลนี้เท่านั้น (ตัดความรับผิดชอบเรียบร้อย) บทความนี้จะแสดงตัวอย่างการดาวน์โหลดวิดีโอจากเว็บต่างๆ อย่างเช่น youtube, udemy, facebook นะครับ โดยเราจะใช้โปรแกรม youtube-dl ในการดาวน์โหลด และใช้ ffmpeg ในการแปลงฟอร์แมตของไฟล์ จริงๆ ตัว youtube-dl มันก็มีให้ใส่พารามิเตอร์ให้เลือกฟอร์แมตของไฟล์นะครับ แต่สุดท้ายมันก็ไปเรียกใช้ ffmpeg ต่ออยู่ดี ซึ้งขั้นตอนในการแปลงฟอร์แมตเนี้ยก็ใช้เวลานานพอสมควร งั้นผมเลยแยกขั้นตอนการดาวน์โหลดและการแปลงฟอร์แมตของไฟล์วิดีโอออกจากกัน โดยเริ่มจากดาวน์โหลดวิดีโอมาก่อน จากนั้นค่อยมาทำการแปลงฟอร์แมตของไฟล์อีกที

ในขั้นตอนการติดตั้งจะแนะนำเฉพาะบน Windows เท่านั้นนะครับ สำหรับผู้ที่ใช้ Linux น่าจะมีพื้นฐานมากกว่าอยู่แล้ว และขั้นตอนการติดตั้งก็ไม่ยากนักคิดว่าคงทำกันได้หมด

ติดตั้ง youtube-dl โดยให้เข้าไปดาวน์โหลดที่ https://rg3.github.io/youtube-dl/ ให้คลิกไปที่เมนู Download และเลือก youtube-dl.exe หลังจากดาวน์โหลด ให้นำไปไว้ที่ c:\youtube-dl\

ติดตั้ง FFmpeg โดยเข้าไปที่ https://ffmpeg.org/download.html และเลือก Windows Packages จะมีลิงค์ไปหน้าดาวน์โหลดสำหรับ Windows ที่ https://ffmpeg.zeranoe.com/builds/ เมื่อดาวน์โหลดมาแล้วให้ unzip และนำไปไว้ที่ c:\ffmpeg\

จากนั้นทำการคอนฟิก Enviroment Variable Path ของ windows โดยให้เข้าไปที่ Control Panel -› System and Security -› System -› Advanced system Setting และเลือกที่ Enviroment Variables

ในส่วนของ System variables ให้เลือกไปที่ Path และเลือก Edit

ทำการเพิ่ม path ของ youtube-dl และ ffmpeg เข้าไปดังรูป

เมื่อเรียบร้อยแล้วให้ลองเปิด command และพิมพ์คำสั่งดังต่อไปนี้ เพื่อตรวจสอบ version กันก่อน ถ้าทุกอย่างเรียบร้อย น่าจะขึ้นประมาณนี้

1
2
youtube-dl --version
ffmpeg -version

และก่อนใช้งานทุกครั้งเราควรสั่ง youtube-dl -U เพื่อทำการ update โปรแกรมให้เป็น version ใหม่สุดอยู่เสมอ

สำหรับการดาวน์โหลดวิดีโอจาก youtube เราสามารถโหลดได้ทั้งแบบเป็น playlist และที่เป็นวิดีโอเดี่ยวๆ โดยสามารถใช้คำสั่งได้ดังต่อไปนี้

แบบเป็น playlist

1
youtube-dl --no-check-certificate --ignore-errors "https://www.youtube.com/playlist?list=PL6B3937A5D230E335"

แบบแยกเป็นรายวิดีโอ

1
youtube-dl --no-check-certificate "https://www.youtube.com/watch?v=YE7VzlLtp-4"

สำหรับ facebook ก็สามารถโหลดได้เช่นกันโดยใช้คำสั่งดังต่อไปนี้

1
youtube-dl --no-check-certificate "https://www.facebook.com/DevExp/videos/1378097708883662/"

และสำหรับวิดีโอที่เราซื้อคอร์สออนไลน์ไว้บน udemy เราสามารถโหลดทั้งคอร์สมาได้ โดยใช้คำสั่งดังต่อไปนี้

1
youtube-dl -u username -p password -o "%(chapter_number)s-%(chapter)s/%(autonumber)s-%(title)s.%(ext)s" "https://www.udemy.com/java-tutorial/"

ในกรณีที่ดาวน์โหลดวิดีโอลงมาแล้ว ไฟล์ที่ได้อาจจะเป็นไฟล์ .mkv หรือนามสกุลอื่นๆ เราสามารถทำการแปลงฟอร์แมตของไฟล์ได้โดยใช้ ffmpeg โดยให้สร้างโฟลเดอร์ใหม่ขึ้นมาก่อน ในที่นี้ผมจะตั้งชื่อโฟลเดอร์ว่า new-mp4 เอาไว้เก็บไฟล์ที่ได้จากการแปลง และใช้คำสั่งสำหรับการแปลงเป็น mp4 ดังนี้

1
ffmpeg -i old-video-file.mkv -vcodec libx264 -profile:v high -acodec aac ./new-mp4/new-video-file.mp4

หรือหากว่าต้องการแปลงทั้งโฟลเดอร์ให้ใช้คำสังดังต่อไปนี้

1
FOR /F "tokens=*" %G IN ('dir /b *') DO ffmpeg -i "%G" -vcodec libx264 -profile:v high -acodec aac "./new-mp4/%~nG.mp4"

อ้างอิง: https://github.com/rg3/youtube-dl/blob/master/README.md

Kitt: Intel® Optimized LINPACK Benchmark on Debian and Ubuntu

13 February, 2017 - 01:03
Got a chance to grab 8 dedicated servers. All of them are identical configuration. Intel Xeon E5-2660 2.20 GHz – 8 Core / 16 Threads 16GB (DDR3) Memory 240GB (SSD) Storage 1 Gbps Network Port And I put Debian on 2 of them and Ubuntu 2 of them. Since I use these servers for computation, I tested … Continue reading Intel® Optimized LINPACK Benchmark on Debian and Ubuntu →

LookHin: การเขียนโปรแกรมเพื่อวิเคราะห์รูปภาพโดยใช้ Google Cloud Vision API

9 February, 2017 - 23:52

Google Cloud Vision สามารถวิเคราะห์ภาพได้ 6 รูปแบบคือ Label, Text, Face, Landmark, Logo, Image Properties ขั้นตอนการวิเคราะห์คือเราต้องทำการ อัพโหลดภาพขึ้นไปที่ Cloud Vision API จากนั้นเราจะได้ค่ากลับมาเป็น JSON ง่ายมากบอกเลย! เราอาจจะเอาความรู้จากบทความนี้มาทำแอพเล่นก็ได้ เช่นว่า ให้ผู้เข้าร่วมกิจกรรมทำการอัพโหลดรูปขึ้นมา และให้ระบบตรวจสอบว่าเป็นภาพอะไร แล้วเอาค่าที่ได้มาทำเป็นแคปชั่นหรือแฮชแทก แล้วอัพโหลดรูปนั้นขึ้นไปที่ Instagram (ดูวิธีการได้จากบทความที่แล้ว) อะไรประมาณนั้น แล้วแต่จะจินตนาการเช่นเคย

ในการใช้งานแบบฟรีเราสามารถอัพโหลดได้ 4MB ต่อภาพ และใช้งานได้ฟรี 1,000 หน่วยต่อเดือน (หน่วยในทีนี้ผมเข้าใจว่าหมายถึงจำนวนการร้องขอการตรวจสอบ เช่นถ้า 1 ภาพเราต้องการให้ตรวจสอบทั้ง Text และ Landmark ก็จะนับเป็น 2 หน่วย) ถ้ามากกว่านั้นก็ต้องเสียตังค์ (ก็สมเหตุสมผล ใช้มากก็ต้องใช้เงินแก้ปัญหาไป)

ขั้นตอนการสมัครเข้าใช้งาน Google Cloud Vision API ให้เข้าไปที่ Cloud Platform Console และคลิกที่ปุ่ม CREATE PROJECT

ตั้งชื่อโปรเจคและใส่ข้อมูลต่างๆ ให้เรียบร้อย

จากนั้นทำการเปิดใช้งาน Cloud Vision API โดยคลิกที่ลิงค์นี้และเลือกโปรเจคที่เราสร้างไว้เมื่อสักครู่ Enable Cloud Vision API

ขั้นตอนถัดไปให้สร้าง API Key โดยให้คลิกเข้าไปที่เมนูรูปแฮมเบอร์เกอร์ด้านซ้ายมือและเลือกไปที่ API Manager และคลิกไปที่เมนู Credentials จากนั้นให้ทำการคลิกที่ Create Credentials และเลือกเป็น API Key

หลังจากนั้นเราจะได้ API Key มาชุดหนึ่ง ให้กด RESTRICT KEY และก็กด Save ในหน้าถัดไปเลยครับ

หลังจากได้ API Key มาแล้ว เราก็มาถึงขั้นตอนการเขียนโปรแกรมหละ ให้ดาวน์โหลดตัวอย่างรูปภาพและโค้ดที่ผมเตรียมไว้ลงไปก่อนครับ google-cloud-vision-api.zip (รูปตัวอย่างผมขโมยมาจากเน็ท ฮาา) เมื่อโหลดมาแล้วจะเห็นไฟล์ google-cloud-vision.php อันนี้เป็นตัวอย่างโค้ดที่ผมเตรียมไว้ให้ ให้ทำการเปลี่ยน API_KEY เป็นของตัวเองนะครับ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
 
// Google Cloud Vision API
$strUrl = "https://vision.googleapis.com/v1/images:annotate?key=API_KEY";
 
$arrHeader = array();
$arrHeader[] = "Content-Type: application/json";
 
 
$objImgData = file_get_contents("test.jpg");
$objImgBase64 =  base64_encode($objImgData);
 
$arrPostData = array();
$arrPostData['requests'][0]['image']['content'] = $objImgBase64;
 
$arrPostData['requests'][0]['features'][0]['type'] = "LABEL_DETECTION";
$arrPostData['requests'][0]['features'][0]['maxResults'] = "5";
 
$arrPostData['requests'][0]['features'][1]['type'] = "FACE_DETECTION";
$arrPostData['requests'][0]['features'][1]['maxResults'] = "5";
 
$arrPostData['requests'][0]['features'][2]['type'] = "TEXT_DETECTION";
$arrPostData['requests'][0]['features'][2]['maxResults'] = "5";
 
$arrPostData['requests'][0]['features'][3]['type'] = "LANDMARK_DETECTION";
$arrPostData['requests'][0]['features'][3]['maxResults'] = "5";
 
$arrPostData['requests'][0]['features'][4]['type'] = "LOGO_DETECTION";
$arrPostData['requests'][0]['features'][4]['maxResults'] = "5";
 
$arrPostData['requests'][0]['features'][5]['type'] = "IMAGE_PROPERTIES";
$arrPostData['requests'][0]['features'][5]['maxResults'] = "5";
 
 
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$strUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $arrHeader);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($arrPostData));
curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close ($ch);
 
print $result;
 
?>

จากนั้นสั่งรันโค้ด เราจะได้ค่าผลลัพธ์กลับมาเป็น JSON เป็นอันเรียบร้อย

อ้างอิง : https://cloud.google.com/vision/docs/

Pages

Creative Commons License ลิขสิทธิ์ของบทความเป็นของเจ้าของบทความแต่ละชิ้น
ผลงานนี้ ใช้สัญญาอนุญาตของครีเอทีฟคอมมอนส์แบบ แสดงที่มา-อนุญาตแบบเดียวกัน 3.0 ที่ยังไม่ได้ปรับแก้