อ่านหน้าเว็บและเน้นเนื้อหาโดยใช้ Amazon Polly PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI.

อ่านหน้าเว็บและเน้นเนื้อหาโดยใช้ Amazon Polly

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

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

ภาพรวมของโซลูชัน

PollyReadsThePage (PRTP)—ในขณะที่เราอ้างถึงโซลูชัน—อนุญาตให้ผู้เผยแพร่หน้าเว็บวางการควบคุมเสียงลงบนหน้าเว็บของตน เมื่อแขกเลือก เล่น บนตัวควบคุม ตัวควบคุมจะอ่านหน้าและเน้นเนื้อหา PRTP ใช้ความสามารถทั่วไปของ Amazon Polly เพื่อสังเคราะห์เสียงพูดจากข้อความ เรียกใช้ Amazon Polly เพื่อสร้างอาร์ติแฟกต์สองรายการสำหรับแต่ละหน้า:

  • เนื้อหาเสียงในรูปแบบที่เบราว์เซอร์เล่นได้: MP3
  • ไฟล์เครื่องหมายคำพูดที่ระบุสำหรับแต่ละประโยคของข้อความ:
    • เวลาระหว่างการเล่นที่อ่านประโยค
    • ตำแหน่งในหน้าประโยคที่ปรากฏ

เมื่อแขกเลือก เล่น, เบราว์เซอร์จะเล่นไฟล์ MP3 เมื่ออ่านเสียงแล้ว เบราว์เซอร์จะตรวจสอบเวลา ค้นหาในไฟล์เครื่องหมายว่าประโยคใดที่ควรอ่านในขณะนั้น ค้นหาตำแหน่งนั้นบนหน้า และไฮไลต์ประโยคนั้น

PRTP ช่วยให้ผู้เยี่ยมชมสามารถอ่านเสียงและภาษาต่างๆ ได้ แต่ละเสียงต้องการไฟล์คู่ของตัวเอง PRTP ใช้เสียงประสาท สำหรับรายการเสียงและภาษาของระบบประสาทที่รองรับ โปรดดูที่ เสียงประสาท. สำหรับรายการเสียงมาตรฐานและเสียงประสาททั้งหมดใน Amazon Polly โปรดดูที่ เสียงใน Amazon Polly.

เราพิจารณาหน้าเว็บสองประเภท: หน้าเว็บแบบคงที่และแบบไดนามิก ใน คงที่ หน้า เนื้อหาจะอยู่ภายในหน้าและเปลี่ยนแปลงเฉพาะเมื่อมีการเผยแพร่หน้าเวอร์ชันใหม่เท่านั้น บริษัทอาจอัปเดตหน้าทุกวันหรือทุกสัปดาห์ซึ่งเป็นส่วนหนึ่งของกระบวนการสร้างเว็บ สำหรับหน้าประเภทนี้ สามารถสร้างไฟล์เสียงไว้ล่วงหน้า ณ เวลาที่สร้างและวางไว้บนเว็บเซิร์ฟเวอร์เพื่อเล่น ดังรูปต่อไปนี้ สคริปต์ PRTP Pre-Gen เรียกใช้ Amazon Polly เพื่อสร้างเสียง มันใช้เป็นอินพุตหน้า HTML เอง และไฟล์การกำหนดค่าซึ่งระบุข้อความจากหน้าที่จะแยก (Text Extract Config). หากละเว้นการกำหนดค่าการแตกไฟล์ สคริปต์ pre-gen จะเลือกข้อความที่เหมาะสมในการดึงออกจากเนื้อหาของหน้า Amazon Polly ส่งออกไฟล์เป็น บริการจัดเก็บข้อมูลอย่างง่ายของ Amazon (Amazon S3) ถัง; สคริปต์คัดลอกไปยังเว็บเซิร์ฟเวอร์ของคุณ เมื่อผู้เยี่ยมชมเล่นเสียง เบราว์เซอร์จะดาวน์โหลด MP3 โดยตรงจากเว็บเซิร์ฟเวอร์ สำหรับไฮไลท์ ห้องสมุดดรอปอิน PRTP.js, ใช้ไฟล์เครื่องหมายเพื่อเน้นข้อความที่กำลังอ่าน

เนื้อหาของ พลวัต หน้าเปลี่ยนแปลงตามการโต้ตอบของผู้เข้าชม ดังนั้นจึงไม่สามารถสร้างเสียงล่วงหน้าได้ แต่ต้องสังเคราะห์แบบไดนามิก ดังรูปต่อไปนี้ เมื่อผู้เยี่ยมชมเล่นเสียง หน้าจะใช้ PRTP.js เพื่อสร้างเสียงใน Amazon Polly และเน้นเสียงที่สังเคราะห์โดยใช้วิธีการเดียวกันกับหน้าสแตติก ในการเข้าถึงบริการของ AWS จากเบราว์เซอร์ ผู้เข้าชมต้องมีข้อมูลประจำตัวของ AWS เราแสดงวิธีใช้ an Amazon Cognito Co พูลข้อมูลประจำตัวเพื่อให้ผู้เยี่ยมชมสามารถเข้าถึง Amazon Polly และบัคเก็ต S3 ได้เพียงพอที่จะแสดงเสียง

เนื้อหาแบบไดนามิก

การสร้างทั้งเสียง Mp3 และเครื่องหมายคำพูดต้องใช้บริการ Polly เพื่อสังเคราะห์อินพุตเดียวกันสองครั้ง อ้างถึง หน้าราคา Amazon Polly เพื่อทำความเข้าใจผลกระทบของต้นทุน รุ่นก่อนช่วยประหยัดค่าใช้จ่ายเนื่องจากการสังเคราะห์จะดำเนินการในเวลาที่สร้างมากกว่าตามความต้องการสำหรับการโต้ตอบของผู้เยี่ยมชมแต่ละครั้ง

รหัสที่มาพร้อมกับโพสต์นี้มีให้ในรูปแบบที่เก็บโอเพ่นซอร์สบน GitHub.

ในการสำรวจโซลูชัน เราทำตามขั้นตอนเหล่านี้:

  1. ตั้งค่าทรัพยากร รวมถึงเซิร์ฟเวอร์บิลด์รุ่นก่อน บัคเก็ต S3 เว็บเซิร์ฟเวอร์ และข้อมูลประจำตัวของ Amazon Cognito
  2. รันการสร้าง pre-gen แบบคงที่และทดสอบหน้าสแตติก
  3. ทดสอบหน้าไดนามิก

เบื้องต้น

ในการรันตัวอย่างนี้ คุณต้องมี บัญชี AWS ได้รับอนุญาตให้ใช้ Amazon Polly, Amazon S3, Amazon Cognito และ (เพื่อวัตถุประสงค์ในการสาธิต) AWS Cloud9.

จัดหาทรัพยากร

เราแบ่งปันและ การก่อตัวของ AWS Cloud เทมเพลตเพื่อสร้างสภาพแวดล้อมการสาธิตแบบสมบูรณ์ในบัญชีของคุณในบัญชีของคุณ เพื่อช่วยให้คุณติดตามไปพร้อมกับโพสต์ หากคุณต้องการตั้งค่า PRTP ในสภาพแวดล้อมของคุณเอง โปรดดูคำแนะนำใน README.md.

หากต้องการจัดเตรียมสภาพแวดล้อมการสาธิตโดยใช้ CloudFormation ให้ดาวน์โหลดสำเนาของ .ก่อน เทมเพลต CloudFormation. จากนั้นทำตามขั้นตอนต่อไปนี้:

  1. บนคอนโซล AWS CloudFormation ให้เลือก สร้างสแต็ก
  2. Choose ด้วยทรัพยากรใหม่ (มาตรฐาน).
  3. เลือก อัปโหลดไฟล์เทมเพลต
  4. Choose เลือกไฟล์ เพื่ออัปโหลดสำเนาในเครื่องของเทมเพลตที่คุณดาวน์โหลด ชื่อของไฟล์คือ prtp.yml.
  5. Choose ถัดไป.
  6. ป้อนชื่อสแต็กที่คุณเลือก ต่อมาคุณป้อนสิ่งนี้อีกครั้งเพื่อแทนที่ .
  7. คุณอาจเก็บค่าเริ่มต้นไว้ใน พารามิเตอร์ มาตรา.
  8. Choose ถัดไป.
  9. ดำเนินการต่อในส่วนที่เหลือ
  10. อ่านและเลือกกล่องกาเครื่องหมายใน ความสามารถในการ มาตรา.
  11. Choose สร้าง stack.
  12. เมื่อสแต็คเสร็จแล้ว ให้หาค่าสำหรับ BucketName ในเอาต์พุตสแต็ก

เราขอแนะนำให้คุณตรวจสอบสแตกกับทีมรักษาความปลอดภัยของคุณก่อนที่จะใช้สภาพแวดล้อมการผลิต

ตั้งค่าเว็บเซิร์ฟเวอร์และเซิร์ฟเวอร์รุ่นก่อนใน AWS Cloud9 IDE

ถัดไป บนคอนโซล AWS Cloud9 ค้นหาสภาพแวดล้อม PRTPDemoCloud9 สร้างโดยกอง CloudFormation เลือก เปิด IDE เพื่อเปิดสภาพแวดล้อม AWS Cloud9 เปิดหน้าต่างเทอร์มินัลแล้วเรียกใช้คำสั่งต่อไปนี้ ซึ่งโคลนรหัส PRTP ตั้งค่าการพึ่งพารุ่นก่อน และเริ่มเว็บเซิร์ฟเวอร์เพื่อทดสอบด้วย:

#Obtain PRTP code
cd /home/ec2-user/environment
git clone https://github.com/aws-samples/amazon-polly-reads-the-page.git

# Navigate to that code
cd amazon-polly-reads-the-page/setup

# Install Saxon and html5 Python lib. For pre-gen.
sh ./setup.sh <StackName>

# Run Python simple HTTP server
cd ..
./runwebserver.sh <IngressCIDR> 

สำหรับ ให้ใช้ชื่อที่คุณตั้งให้ CloudFormation stack สำหรับ ระบุช่วงของที่อยู่ IP ที่อนุญาตให้เข้าถึงเว็บเซิร์ฟเวอร์ ในการจำกัดการเข้าถึงเบราว์เซอร์บนเครื่องท้องถิ่นของคุณ ให้ค้นหาที่อยู่ IP ของคุณโดยใช้ https://whatismyipaddress.com/ และต่อท้าย /32 เพื่อระบุช่วง ตัวอย่างเช่น ถ้า IP ของคุณคือ 10.2.3.4, use 10.2.3.4/32. เซิร์ฟเวอร์รับฟังพอร์ต 8080 ที่อยู่ IP สาธารณะที่เซิร์ฟเวอร์รับฟังจะได้รับในเอาต์พุต ตัวอย่างเช่น:

Public IP is

3.92.33.223

ทดสอบหน้าคงที่

ในเบราว์เซอร์ของคุณ ให้ไปที่ PRTPStaticDefault.html. (หากคุณใช้การสาธิต URL คือ http://<cloud9host>:8080/web/PRTPStaticDefault.htmlที่นี่มี คือที่อยู่ IP สาธารณะที่คุณค้นพบในการตั้งค่า IDE) เลือก เล่น บนตัวควบคุมเสียงที่ด้านบน ฟังเสียงและดูไฮไลท์ สำรวจการควบคุมโดยเปลี่ยนความเร็ว เปลี่ยนเสียง หยุดชั่วคราว กรอไปข้างหน้า และกรอกลับ ภาพหน้าจอต่อไปนี้แสดงหน้า ข้อความ "ข้ามย่อหน้าที่ซ่อน" ถูกเน้นเพราะกำลังอ่านอยู่

อ่านหน้าเว็บและเน้นเนื้อหาโดยใช้ Amazon Polly PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI.

ลองเหมือนกันสำหรับ PRTPStaticConfig.html และ PRTPStaticCustom.html. ผลลัพธ์มีความคล้ายคลึงกัน ตัวอย่างเช่น ทั้งสามคนอ่านข้อความแสดงแทนรูปภาพของแมว (“ภาพสุ่มของแมว”) ทั้งสามอ่าน NE, NW, SE และ SW เป็นคำเต็ม (“ตะวันออกเฉียงเหนือ” “ตะวันตกเฉียงเหนือ” “ตะวันออกเฉียงใต้” “ตะวันตกเฉียงใต้”) โดยใช้ประโยชน์จากพจนานุกรมของ Amazon Polly

สังเกตความแตกต่างที่สำคัญของเสียง:

  • PRTPStaticDefault.html อ่านข้อความทั้งหมดในเนื้อหาของหน้า รวมถึงส่วนสรุปที่ด้านล่างด้วย "ความคิดของคุณเป็นคำเดียว" "ส่งคำถาม" "อัปเดตล่าสุด 1 เมษายน 2020" และ "คำถามสำหรับทีมนักพัฒนาซอฟต์แวร์" PRTPStaticConfig.html และ PRTPStaticCustom.html อย่าอ่านข้อความเหล่านี้เนื่องจากแยกส่วนสรุปจากการสังเคราะห์เสียงพูดอย่างชัดเจน
  • PRTPStaticCustom.html อ่าน QB สินค้าขายดี ตารางแตกต่างจากที่อื่น โดยจะอ่านสามแถวแรกเท่านั้น และอ่านหมายเลขแถวสำหรับแต่ละแถว มันซ้ำคอลัมน์สำหรับแต่ละแถว PRTPStaticCustom.html ใช้การแปลงแบบกำหนดเองเพื่อปรับแต่งการอ่านข้อมูลของตาราง หน้าอื่นใช้การแสดงตารางเริ่มต้น
  • PRTPStaticCustom.html อ่าน "Tom Brady" ด้วยความดังกว่าข้อความที่เหลือ ใช้ภาษามาร์กอัปการสังเคราะห์เสียงพูด (SSML) prosody แท็กเพื่อปรับแต่งการอ่านของ Tom Brady หน้าอื่นๆ ไม่ได้ปรับแต่งในลักษณะนี้
  • PRTPStaticCustom.htmlต้องขอบคุณการแปลงแบบกำหนดเอง อ่านไทล์หลักในลำดับ NW, SW, NE, SE; นั่นคือ มันอ่านว่า "บทความของวันนี้" "คำคมประจำวัน" "รูปภาพประจำวัน" "เรื่องตลกประจำวัน" หน้าอื่นๆ อ่านเรียงตามลำดับที่ปรากฏอยู่ในลำดับ NW, NE, SW, SE ที่ปรากฏใน HTML: “บทความของวันนี้” “ภาพถ่ายประจำวัน” “คำคมประจำวัน” “เรื่องตลกของ วัน."

มาเจาะลึกกันถึงวิธีการสร้างเสียง และวิธีที่หน้าเน้นข้อความ

เครื่องกำเนิดล่วงหน้าแบบคงที่

repo GitHub ของเรามีไฟล์เสียงที่สร้างไว้ล่วงหน้าสำหรับ PRPTStatic หน้า แต่ถ้าคุณต้องการสร้างด้วยตัวเอง จาก bash shell ใน AWS Cloud9 IDE ให้รันคำสั่งต่อไปนี้:

# navigate to examples
cd /home/ec2-user/environment/amazon-polly-reads-the-page-blog/pregen/examples

# Set env var for my S3 bucket. Example, I called mine prtp-output
S3_BUCKET=prtp-output # Use output BucketName from CloudFormation

#Add lexicon for pronuniciation of NE NW SE NW
#Script invokes aws polly put-lexicon
./addlexicon.sh.

#Gen each variant
./gen_default.sh
./gen_config.sh
./gen_custom.sh

ตอนนี้เรามาดูกันว่าสคริปต์เหล่านั้นทำงานอย่างไร

กรณีเริ่มต้น

เราเริ่มต้นด้วย gen_default.sh:

cd ..
python FixHTML.py ../web/PRTPStaticDefault.html  
   example/tmp_wff.html
./gen_ssml.sh example/tmp_wff.html generic.xslt example/tmp.ssml
./run_polly.sh example/tmp.ssml en-US Joanna 
   ../web/polly/PRTPStaticDefault compass
./run_polly.sh example/tmp.ssml en-US Matthew 
   ../web/polly/PRTPStaticDefault compass

สคริปต์เริ่มต้นด้วยการรันโปรแกรม Python FixHTML.py เพื่อสร้างไฟล์ HTML ต้นทาง PRTPStaticDefault.html มีรูปร่างที่ดี มันเขียนไฟล์ที่มีรูปแบบที่ดีไปยัง example/tmp_wff.html. ขั้นตอนนี้มีความสำคัญด้วยเหตุผลสองประการ:

  • HTML ต้นทางส่วนใหญ่ไม่ได้มีรูปแบบที่ดี ขั้นตอนนี้ซ่อมแซม HTML ต้นทางให้มีรูปแบบที่ดี ตัวอย่างเช่น หน้า HTML จำนวนมากไม่ปิด P องค์ประกอบ ขั้นตอนนี้จะปิดพวกเขา
  • เราติดตามตำแหน่งที่เราพบข้อความในหน้า HTML เราจำเป็นต้องติดตามตำแหน่งโดยใช้โครงสร้าง document object model (DOM) เดียวกับที่เบราว์เซอร์ใช้ ตัวอย่างเช่น เบราว์เซอร์จะเพิ่ม a . โดยอัตโนมัติ TBODY ไปยัง TABLE. โปรแกรม Python ติดตามการซ่อมแซมที่มีรูปแบบที่ดีเช่นเดียวกับเบราว์เซอร์

gen_ssml.sh ใช้ HTML ที่มีรูปแบบเหมาะสมเป็นอินพุต ใช้การแปลง XML สไตล์ชีต (XSLT) กับมัน และส่งออกไฟล์ SSML (SSML เป็นภาษาใน Amazon Polly เพื่อควบคุมวิธีการแสดงเสียงจากข้อความ) ในตัวอย่างปัจจุบัน อินพุตคือ example/tmp_wff.html. ผลลัพธ์คือ example/tmp.ssml. งานของการแปลงคือตัดสินใจว่าจะดึงข้อความใดจาก HTML และฟีดไปยัง Amazon Polly generic.xslt เป็นการแปลง XSLT เริ่มต้นที่สมเหตุสมผลสำหรับหน้าเว็บส่วนใหญ่ ในตัวอย่างโค้ดต่อไปนี้ จะไม่รวมการควบคุมเสียง ส่วนหัว HTML และองค์ประกอบ HTML เช่น script และ form. นอกจากนี้ยังไม่รวมองค์ประกอบที่มีแอตทริบิวต์ที่ซ่อนอยู่ ประกอบด้วยองค์ประกอบที่มักประกอบด้วยข้อความ เช่น P, H1และ SPAN. สำหรับสิ่งเหล่านี้ มันแสดงทั้งเครื่องหมาย รวมถึงนิพจน์ XPath แบบเต็มขององค์ประกอบ และค่าขององค์ประกอบ

<!-- skip the header -->
<xsl:template match="html/head">
</xsl:template>

<!-- skip the audio itself -->
<xsl:template match="html/body/table[@id='prtp-audio']">
</xsl:template>

<!-- For the body, work through it by applying its templates. This is the default. -->
<xsl:template match="html/body">
<speak>
      <xsl:apply-templates />
</speak>
</xsl:template>

<!-- skip these -->
<xsl:template match="audio|option|script|form|input|*[@hidden='']">
</xsl:template>

<!-- include these -->
<xsl:template match="p|h1|h2|h3|h4|li|pre|span|a|th/text()|td/text()">
<xsl:for-each select=".">
<p>
      <mark>
          <xsl:attribute name="name">
          <xsl:value-of select="prtp:getMark(.)"/>
          </xsl:attribute>
      </mark>
      <xsl:value-of select="normalize-space(.)"/>
</p>
</xsl:for-each>
</xsl:template>

ต่อไปนี้คือข้อมูลโค้ด SSML ที่แสดงผล ข้อมูลนี้ป้อนเป็นข้อมูลเข้าของ Amazon Polly ตัวอย่างเช่น สังเกตว่าข้อความ "ข้ามย่อหน้าที่ซ่อน" นั้นให้อ่านในไฟล์เสียง และเราเชื่อมโยงกับเครื่องหมาย ซึ่งบอกเราว่าข้อความนี้เกิดขึ้นในตำแหน่งบนหน้าเว็บที่กำหนดโดยนิพจน์ XPath /html/body[1]/div[2]/ul[1]/li[1].

<speak>
<p><mark name="/html/body[1]/div[1]/h1[1]"/>PollyReadsThePage Normal Test Page</p>
<p><mark name="/html/body[1]/div[2]/p[1]"/>PollyReadsThePage is a test page for audio readout with highlights.</p>
<p><mark name="/html/body[1]/div[2]/p[2]"/>Here are some features:</p>
<p><mark name="/html/body[1]/div[2]/ul[1]/li[1]"/>Skips hidden paragraph</p>
<p><mark name="/html/body[1]/div[2]/ul[1]/li[2]"/>Speaks but does not highlight collapsed content</p>
…
</speak>

ในการสร้างเสียงใน Amazon Polly เราเรียกสคริปต์ run_polly.sh. มันวิ่ง อินเทอร์เฟซบรรทัดคำสั่ง AWS AWS (AWS CLI) คำสั่ง aws polly start-speech-synthesis-task สองครั้ง: หนึ่งครั้งเพื่อสร้างเสียง MP3 และอีกครั้งเพื่อสร้างไฟล์เครื่องหมาย เนื่องจากการสร้างเป็นแบบอะซิงโครนัส สคริปต์จึงสำรวจจนกว่าจะพบเอาต์พุตในบัคเก็ต S3 ที่ระบุ เมื่อพบผลลัพธ์ มันจะดาวน์โหลดไปยังเซิร์ฟเวอร์บิลด์และคัดลอกไฟล์ไปที่ web/polly โฟลเดอร์ ต่อไปนี้เป็นรายการของโฟลเดอร์เว็บ:

  • PRTStaticDefault.html
  • PRTStaticConfig.html
  • PRTStaticCustom.html
  • PRTP.js
  • พอลลี่/PRTPStaticDefault/Joanna.mp3, Joanna.marks, Matthew.mp3, Matthew.marks
  • พอลลี่/PRTPStaticConfig/Joanna.mp3, Joanna.marks, Matthew.mp3, Matthew.marks
  • พอลลี่/PRTPStaticCustom/Joanna.mp3, Joanna.marks, Matthew.mp3, Matthew.marks

แต่ละหน้ามีชุดไฟล์ MP3 และทำเครื่องหมายเฉพาะเสียงของตัวเอง ไฟล์เหล่านี้เป็นไฟล์ที่สร้างไว้ล่วงหน้า หน้านี้ไม่จำเป็นต้องเรียกใช้ Amazon Polly ในขณะใช้งานจริง ไฟล์เป็นส่วนหนึ่งของเว็บบิลด์

กรณีขับเคลื่อนด้วยการกำหนดค่า

ถัดไปพิจารณา gen_config.sh:

cd ..
python FixHTML.py ../web/PRTPStaticConfig.html 
  example/tmp_wff.html
python ModGenericXSLT.py example/transform_config.json 
  example/tmp.xslt
./gen_ssml.sh example/tmp_wff.html example/tmp.xslt 
  example/tmp.ssml
./run_polly.sh example/tmp.ssml en-US Joanna 
  ../web/polly/PRTPStaticConfig compass
./run_polly.sh example/tmp.ssml en-US Matthew 
  ../web/polly/PRTPStaticConfig compass

สคริปต์คล้ายกับสคริปต์ในกรณีเริ่มต้น แต่เส้นที่เป็นตัวหนาบ่งบอกถึงความแตกต่างหลัก แนวทางของเราขับเคลื่อนโดยการกำหนดค่า เราปรับแต่งเนื้อหาที่จะดึงออกจากหน้าโดยระบุสิ่งที่จะแยกผ่านการกำหนดค่า ไม่ใช่โค้ด โดยเฉพาะอย่างยิ่ง เราใช้ไฟล์ JSON transform_config.jsonซึ่งระบุว่าเนื้อหาที่จะรวมเป็นองค์ประกอบที่มีรหัส title, main, maintableและ qbtable. องค์ประกอบที่มี ID wrapup ควรได้รับการยกเว้น ดูรหัสต่อไปนี้:

{
 "inclusions": [ 
 	{"id" : "title"} , 
 	{"id": "main"}, 
 	{"id": "maintable"}, 
 	{"id": "qbtable" }
 ],
 "exclusions": [
 	{"id": "wrapup"}
 ]
}

เรารันโปรแกรม Python ModGenericXSLT.py ในการปรับเปลี่ยน generic.xsltใช้ในกรณีเริ่มต้นเพื่อใช้การรวมและการยกเว้นที่เราระบุไว้ใน transform_config.json. โปรแกรมเขียนผลลัพธ์ไปยังไฟล์ temp (example/tmp.xslt) ซึ่งส่งผ่านไปยัง gen_ssml.sh เมื่อมีการแปลง XSLT

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

กรณีการปรับแต่ง

สุดท้ายนี้ พิจารณา gen_custom.sh:

cd ..
python FixHTML.py ../web/PRTPStaticCustom.html 
   example/tmp_wff.html
./gen_ssml.sh example/tmp_wff.html example/custom.xslt  
   example/tmp.ssml
./run_polly.sh example/tmp.ssml en-US Joanna 
   ../web/polly/PRTPStaticCustom compass
./run_polly.sh example/tmp.ssml en-US Matthew 
   ../web/polly/PRTPStaticCustom compass

สคริปต์นี้เกือบจะเหมือนกับสคริปต์เริ่มต้น ยกเว้นว่าจะใช้ XSLT ของตัวเอง—example/custom.xslt—แทนที่จะเป็น XSLT ทั่วไป ต่อไปนี้เป็นตัวอย่างข้อมูลของ XSLT:

<!-- Use NW, SW, NE, SE order for main tiles! -->
<xsl:template match="*[@id='maintable']">
    <mark>
        <xsl:attribute name="name">
        <xsl:value-of select="stats:getMark(.)"/>
        </xsl:attribute>
    </mark>
    <xsl:variable name="tiles" select="./tbody"/>
    <xsl:variable name="tiles-nw" select="$tiles/tr[1]/td[1]"/>
    <xsl:variable name="tiles-ne" select="$tiles/tr[1]/td[2]"/>
    <xsl:variable name="tiles-sw" select="$tiles/tr[2]/td[1]"/>
    <xsl:variable name="tiles-se" select="$tiles/tr[2]/td[2]"/>
    <xsl:variable name="tiles-seq" select="($tiles-nw,  $tiles-sw, $tiles-ne, $tiles-se)"/>
    <xsl:for-each select="$tiles-seq">
         <xsl:apply-templates />  
    </xsl:for-each>
</xsl:template>   

<!-- Say Tom Brady load! -->
<xsl:template match="span[@style = 'color:blue']" >
<p>
      <mark>
          <xsl:attribute name="name">
          <xsl:value-of select="prtp:getMark(.)"/>
          </xsl:attribute>
      </mark>
      <prosody volume="x-loud">Tom Brady</prosody>
</p>
</xsl:template>

หากคุณต้องการศึกษาโค้ดโดยละเอียด โปรดดูสคริปต์และโปรแกรมใน GitHub repo

การตั้งค่าเบราว์เซอร์และไฮไลท์

หน้าสแตติกประกอบด้วยการควบคุมเสียง HTML5 ซึ่งใช้ไฟล์ MP3 ที่สร้างโดย Amazon Polly เป็นแหล่งกำเนิดเสียงและอยู่บนเว็บเซิร์ฟเวอร์:

<audio id="audio" controls>
  <source src="polly/PRTPStaticDefault/en/Joanna.mp3" type="audio/mpeg">
</audio>

ในขณะที่โหลด หน้าจะโหลดไฟล์เครื่องหมายที่สร้างโดย Amazon Polly ด้วย สิ่งนี้เกิดขึ้นใน PRTP.js ไฟล์ซึ่งหน้า HTML รวมอยู่ด้วย ต่อไปนี้เป็นตัวอย่างบางส่วนของไฟล์เครื่องหมายสำหรับ PRTPStaticDefault:

{“time”:11747,“type”:“sentence”,“start”:289,“end”:356,“value”:“PollyReadsThePage is a test page for audio readout with highlights.“}
{“time”:15784,“type”:“ssml”,“start”:363,“end”:403,“value”:“/html/body[1]/div[2]/p[2]“}
{“time”:16427,“type”:“sentence”,“start”:403,“end”:426,“value”:“Here are some features:“}
{“time”:17677,“type”:“ssml”,“start”:433,“end”:480,“value”:“/html/body[1]/div[2]/ul[1]/li[1]“}
{“time”:18344,“type”:“sentence”,“start”:480,“end”:502,“value”:“Skips hidden paragraph”}
{“time”:19894,“type”:“ssml”,“start”:509,“end”:556,“value”:“/html/body[1]/div[2]/ul[1]/li[2]“}
{“time”:20537,“type”:“sentence”,“start”:556,“end”:603,“value”:“Speaks but does not highlight collapsed content”}

ในระหว่างการเล่นเสียง มีตัวจัดการเหตุการณ์ตัวจับเวลาเสียงใน PRTP.js ที่ตรวจสอบเวลาปัจจุบันของเสียง ค้นหาข้อความที่จะไฮไลท์ ค้นหาตำแหน่งบนหน้า และไฮไลท์ ข้อความที่จะไฮไลท์เป็นรายการประเภท sentence ในไฟล์เครื่องหมาย ตำแหน่งคือนิพจน์ XPath ในแอตทริบิวต์ชื่อของรายการประเภท SSML ที่นำหน้าประโยค ตัวอย่างเช่น ถ้าเวลาคือ 18400 ตามไฟล์เครื่องหมาย ประโยคที่จะเน้นคือ "ข้ามย่อหน้าที่ซ่อน" ซึ่งเริ่มต้นที่ 18334 ตำแหน่งคือรายการ SSML เวลา 17667: /html/body[1]/div[2]/ul[1]/li[1].

ทดสอบหน้าไดนามิก

หน้า PRTPDynamic.html สาธิตการอ่านเสียงแบบไดนามิกโดยใช้วิธีการแยกเสียงเริ่มต้น ที่ขับเคลื่อนด้วยการกำหนดค่า และแบบกำหนดเอง

กรณีเริ่มต้น

ในเบราว์เซอร์ของคุณ ให้ไปที่ PRTPDynamic.html. หน้านี้มีพารามิเตอร์การค้นหาหนึ่งรายการ dynOptionซึ่งยอมรับค่า default, configและ custom. มีค่าเริ่มต้นเป็น defaultดังนั้นคุณอาจละเว้นได้ในกรณีนี้ หน้านี้มีสองส่วนที่มีเนื้อหาแบบไดนามิก:

  • บทความล่าสุด – เปลี่ยนบ่อยตลอดวัน
  • นักปรัชญากรีก ค้นหาตามวันที่ – อนุญาตให้ผู้เข้าชมค้นหานักปรัชญากรีกตามวันที่และแสดงผลในตาราง

อ่านหน้าเว็บและเน้นเนื้อหาโดยใช้ Amazon Polly PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI.

สร้างเนื้อหาบางส่วนใน นักปรัชญากรีก โดยป้อนช่วงวันที่ -800 ถึง 0 ตามที่แสดงในตัวอย่าง จากนั้นเลือก หา.

ตอนนี้เล่นเสียงโดยเลือก เล่น ในการควบคุมเสียง

เบื้องหลัง หน้าเรียกใช้โค้ดต่อไปนี้เพื่อแสดงผลและเล่นเสียง:

   buildSSMLFromDefault();
   chooseRenderAudio();
   setVoice();

ขั้นแรกให้เรียกใช้ฟังก์ชัน buildSSMLFromDefault in PRTP.js เพื่อแยกข้อความส่วนใหญ่ออกจากเนื้อหาของหน้า HTML ฟังก์ชันนั้นดำเนินการตามแผนผัง DOM โดยมองหาข้อความในองค์ประกอบทั่วไป เช่น p, h1, pre, spanและ td. โดยไม่สนใจข้อความในองค์ประกอบที่มักจะไม่มีข้อความให้อ่านออกเสียง เช่น audio, optionและ script. สร้างมาร์กอัป SSML เพื่อป้อนให้กับ Amazon Polly ต่อไปนี้เป็นตัวอย่างที่แสดงการแยกแถวแรกจาก philosopher ตาราง:

<speak>
...
  <p><mark name="/HTML[1]/BODY[1]/DIV[3]/DIV[1]/DIV[1]/TABLE[1]/TBODY[1]/TR[2]/TD[1]"/>Thales</p>
  <p><mark name="/HTML[1]/BODY[1]/DIV[3]/DIV[1]/DIV[1]/TABLE[1]/TBODY[1]/TR[2]/TD[2]"/>-624 to -546</p>
  <p><mark name="/HTML[1]/BODY[1]/DIV[3]/DIV[1]/DIV[1]/TABLE[1]/TBODY[1]/TR[2]/TD[3]"/>Miletus</p>
  <p><mark name="/HTML[1]/BODY[1]/DIV[3]/DIV[1]/DIV[1]/TABLE[1]/TBODY[1]/TR[2]/TD[4]"/>presocratic</p>
...
</speak>

พื้นที่ chooseRenderAudio ฟังก์ชันมา PRTP.js เริ่มต้นด้วยการเริ่มต้น AWS SDK สำหรับ Amazon Cognito, Amazon S3 และ Amazon Polly การเริ่มต้นนี้เกิดขึ้นเพียงครั้งเดียว ถ้า chooseRenderAudio ถูกเรียกอีกครั้งเนื่องจากเนื้อหาของหน้ามีการเปลี่ยนแปลง การเริ่มต้นถูกข้ามไป ดูรหัสต่อไปนี้:

AWS.config.region = env.REGION
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
            IdentityPoolId: env.IDP});
audioTracker.sdk.connection = {
   polly: new AWS.Polly({apiVersion: '2016-06-10'}),
   s3: new AWS.S3()
};

มันสร้างเสียง MP3 จาก Amazon Polly การสร้างเป็นแบบซิงโครนัสสำหรับอินพุต SSML ขนาดเล็กและอะซิงโครนัส (พร้อมเอาต์พุตที่ส่งไปยังบัคเก็ต S3) สำหรับอินพุต SSML ขนาดใหญ่ (มากกว่า 6,000 อักขระ) ในกรณีแบบซิงโครนัส เราขอให้ Amazon Polly จัดเตรียมไฟล์ MP3 โดยใช้ URL ที่กำหนดไว้ล่วงหน้า เมื่อเอาต์พุตที่สังเคราะห์พร้อมแล้ว เราตั้งค่า src แอตทริบิวต์ของตัวควบคุมเสียงไปยัง URL นั้นและโหลดตัวควบคุม จากนั้นเราขอไฟล์เครื่องหมายและโหลดในลักษณะเดียวกับในกรณีคงที่ ดูรหัสต่อไปนี้:

// create signed URL
const signer = new AWS.Polly.Presigner(pollyAudioInput, audioTracker.sdk.connection.polly);

// call Polly to get MP3 into signed URL
signer.getSynthesizeSpeechUrl(pollyAudioInput, function(error, url) {
  // Audio control uses signed URL
  audioTracker.audioControl.src =
    audioTracker.sdk.audio[audioTracker.voice];
  audioTracker.audioControl.load();

  // call Polly to get marks
  audioTracker.sdk.connection.polly.synthesizeSpeech(
    pollyMarksInput, function(markError, markData) {
    const marksStr = new
      TextDecoder().decode(markData.AudioStream);
    // load marks into page the same as with static
    doLoadMarks(marksStr);
  });
});

กรณีขับเคลื่อนด้วยการกำหนดค่า

ในเบราว์เซอร์ของคุณ ให้ไปที่ PRTPDynamic.html?dynOption=config. เล่นเสียง การเล่นเสียงคล้ายกับกรณีเริ่มต้น แต่มีความแตกต่างเล็กน้อย โดยเฉพาะอย่างยิ่ง เนื้อหาบางส่วนถูกข้ามไป

เบื้องหลังเมื่อใช้ the config ตัวเลือก หน้าจะแยกเนื้อหาที่แตกต่างจากในกรณีเริ่มต้น ในกรณีเริ่มต้น หน้าจะใช้ buildSSMLFromDefault. ในกรณีที่ขับเคลื่อนด้วยการกำหนดค่า หน้าจะระบุส่วนที่ต้องการรวมและยกเว้น:

const ssml = buildSSMLFromConfig({
	 "inclusions": [ 
	 	{"id": "title"}, 
	 	{"id": "main"}, 
	 	{"id": "maintable"}, 
	 	{"id": "phil-result"},
	 	{"id": "qbtable"}, 
	 ],
	 "exclusions": [
	 	{"id": "wrapup"}
	 ]
	});

พื้นที่ buildSSMLFromConfig ฟังก์ชันที่กำหนดไว้ใน PRTP.js, เดินบนต้นไม้ DOM ในแต่ละส่วนที่มี ID อยู่ใต้ inclusions. โดยจะแยกเนื้อหาจากแต่ละรายการและรวมเข้าด้วยกันตามลำดับที่ระบุ เพื่อสร้างเอกสาร SSML ไม่รวมส่วนที่ระบุภายใต้ exclusions. ดึงเนื้อหาจากแต่ละส่วนในลักษณะเดียวกัน buildSSMLFromDefault ดึงเนื้อหาออกจากเนื้อหาของหน้า

กรณีการปรับแต่ง

ในเบราว์เซอร์ของคุณ ให้ไปที่ PRTPDynamic.html?dynOption=custom. เล่นเสียง มีความแตกต่างที่เห็นได้ชัดเจนสามประการ ให้สังเกตสิ่งเหล่านี้และพิจารณาโค้ดที่กำหนดเองที่ทำงานอยู่เบื้องหลัง:

  • มันอ่านไทล์หลักในลำดับ NW, SW, NE, SE รหัสที่กำหนดเองรับแต่ละบล็อกเซลล์เหล่านี้จาก maintable และเพิ่มลงใน SSML ในคำสั่ง NW, SW, NE, SE:
const nw = getElementByXpath("//*[@id='maintable']//tr[1]/td[1]");
const sw = getElementByXpath("//*[@id='maintable']//tr[2]/td[1]");
const ne = getElementByXpath("//*[@id='maintable']//tr[1]/td[2]");
const se = getElementByXpath("//*[@id='maintable']//tr[2]/td[2]");
[nw, sw, ne, se].forEach(dir => buildSSMLSection(dir, []));

  • “ทอม เบรดี้” พูดเสียงดัง โค้ดที่กำหนดเองใส่ข้อความ "Tom Brady" ไว้ใน SSML prosody แท็ก:
if (cellText == "Tom Brady") {
   addSSMLMark(getXpathOfNode( node.childNodes[tdi]));
   startSSMLParagraph();
   startSSMLTag("prosody", {"volume": "x-loud"});
   addSSMLText(cellText);
   endSSMLTag();
   endSSMLParagraph();
}

  • มันอ่านเฉพาะสามแถวแรกของตารางกองหลัง มันอ่านส่วนหัวของคอลัมน์สำหรับแต่ละแถว ตรวจสอบรหัสใน repo GitHub เพื่อดูว่ามีการใช้งานอย่างไร

ทำความสะอาด

เพื่อหลีกเลี่ยงการเรียกเก็บเงินในอนาคต ให้ลบ CloudFormation stack

สรุป

ในโพสต์นี้ เราสาธิตวิธีแก้ปัญหาทางเทคนิคสำหรับปัญหาทางธุรกิจที่มีมูลค่าสูง: วิธีใช้ Amazon Polly เพื่ออ่านเนื้อหาของหน้าเว็บและเน้นเนื้อหาในขณะที่กำลังอ่าน เราแสดงสิ่งนี้โดยใช้ทั้งหน้าแบบคงที่และแบบไดนามิก ในการดึงเนื้อหาออกจากเพจ เราใช้ DOM Traversal และ XSLT เพื่อความสะดวกในการเน้น เราใช้ความสามารถเครื่องหมายคำพูดใน Amazon Polly

เรียนรู้เพิ่มเติมเกี่ยวกับ Amazon Polly โดยไปที่ หน้าบริการ.

อย่าลังเลที่จะถามคำถามในความคิดเห็น


เกี่ยวกับผู้แต่ง

อ่านหน้าเว็บและเน้นเนื้อหาโดยใช้ Amazon Polly PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI.ไมค์ ฮาวีย์ เป็นสถาปนิกโซลูชันสำหรับ AWS ที่มีประสบการณ์มากกว่า 25 ปีในการสร้างแอปพลิเคชันระดับองค์กร ไมค์เป็นผู้เขียนหนังสือสองเล่มและบทความมากมาย เยี่ยมชมอเมซอนของเขา หน้าผู้เขียน อ่านเพิ่มเติม

อ่านหน้าเว็บและเน้นเนื้อหาโดยใช้ Amazon Polly PlatoBlockchain Data Intelligence ค้นหาแนวตั้ง AI.วิเนต คัชวาหะ เป็น Solutions Architect ของ AWS ที่มีความเชี่ยวชาญด้านแมชชีนเลิร์นนิง เขามีหน้าที่รับผิดชอบในการช่วยเหลือลูกค้าสถาปนิกปริมาณงานที่ปรับขนาดได้ ปลอดภัย และคุ้มค่าบน AWS

ประทับเวลา:

เพิ่มเติมจาก AWS Machine Learning AWS