เบเบฒเบ™เบชเบณเบซเบผเบงเบ”เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ Mediastreamer2 VoIP. เบžเบฒเบเบ—เบต 9

เป€เบญเบเบฐเบชเบฒเบ™เบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบกเปเบกเปˆเบ™เป€เบญเบปเบฒเบกเบฒเบˆเบฒเบเบ‚เบญเบ‡เบ‚เป‰เบญเบ เบŠเปˆเบญเบ‡ zen.

Duplex intercom

เบเบฒเบ™เบชเบณเบซเบผเบงเบ”เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ Mediastreamer2 VoIP. เบžเบฒเบเบ—เบต 9

เปƒเบ™เบ—เบตเปˆเบชเบธเบ” เบšเบปเบ”เบ„เบงเบฒเบก intercom duplex เป„เบ”เป‰เบ–เบทเบเบ›เบฐเบเบฒเบ”, เปเบฅเบฐเปƒเบ™เบซเบ™เบถเปˆเบ‡เบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบฎเบฑเบ”เปƒเบซเป‰เบกเบฑเบ™.

เปเบœเบ™เบงเบฒเบ”เปเบกเปˆเบ™เบชเบฐเปเบ”เบ‡เบขเบนเปˆเปƒเบ™เบฎเบนเบšเบซเบปเบงเบ‚เปเป‰. เบฅเบฐเบšเบปเบšเบ•เปˆเบญเบ‡เป‚เบชเป‰เบ•เปˆเปเบฒเบ‚เบญเบ‡เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ›เบฐเบเบญเบšเป€เบ›เบฑเบ™เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เบชเบฒเบเบชเบปเปˆเบ‡, เป€เบŠเบดเปˆเบ‡เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบˆเบฒเบเบšเบฑเบ”เบชเบฝเบ‡. เบกเบฑเบ™เบชเบฐเบซเบ™เบญเบ‡เบ•เบปเบงเบขเปˆเบฒเบ‡เบชเบฑเบ™เบเบฒเบ™เบˆเบฒเบเป„เบกเป‚เบ„เป‚เบŸเบ™. เป‚เบ”เบเบ„เปˆเบฒเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™, เบ™เบตเป‰เป€เบเบตเบ”เบ‚เบทเป‰เบ™เปƒเบ™เบญเบฑเบ”เบ•เบฒ 8000 เบ•เบปเบงเบขเปˆเบฒเบ‡เบ•เปเปˆเบงเบดเบ™เบฒเบ—เบต. เบ„เบงเบฒเบกเป€เบฅเบดเบเบ‚เบญเบ‡เบšเบดเบ”เบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเบ•เบปเบงเบเบญเบ‡เบชเบฝเบ‡เบ‚เบญเบ‡ media streamer เปƒเบŠเป‰เปเบกเปˆเบ™ 16 bits (เบญเบฑเบ™เบ™เบตเป‰เบšเปเปˆเบชเปเบฒเบ„เบฑเบ™; เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ‚เบฝเบ™เบ•เบปเบงเบเบญเบ‡เบ—เบตเปˆเบˆเบฐเป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบšเบ„เบงเบฒเบกเป€เบฅเบดเบเบšเบดเบ”เบ—เบตเปˆเบชเบนเบ‡เบเบงเปˆเบฒ). เบ‚เปเป‰เบกเบนเบ™เบ–เบทเบเบˆเบฑเบ”เป€เบ›เบฑเบ™เบเบธเปˆเบกเบ‚เบญเบ‡ 160 เบ•เบปเบงเบขเปˆเบฒเบ‡. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เปเบ•เปˆเบฅเบฐเบ•เบฑเบ™เปเบกเปˆเบ™ 320 bytes เปƒเบ™เบ‚เบฐเบซเบ™เบฒเบ”. เบ•เปเปˆเป„เบ›, เบžเบงเบเป€เบฎเบปเบฒเปƒเบซเป‰เบ‚เปเป‰เบกเบนเบ™เป€เบ‚เบปเป‰เบฒเปƒเบ™เบเบฒเบ™เบ›เป‰เบญเบ™เบ‚เปเป‰เบกเบนเบ™เบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบเปเบฒเป€เบ™เบตเบ”, เป€เบŠเบดเปˆเบ‡, เป€เบกเบทเปˆเบญเบ›เบดเบ”, เปเบกเปˆเบ™ "เป‚เบ›เปˆเบ‡เปƒเบช" เบเบฑเบšเบ‚เปเป‰เบกเบนเบ™. เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เป€เบžเบตเปˆเบกเบกเบฑเบ™เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ—เบตเปˆเป€เบˆเบปเป‰เบฒเป€เบšเบทเปˆเบญเบ—เบตเปˆเบˆเบฐเป€เบงเบปเป‰เบฒเป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เป„เบกเป‚เบ„เป‚เบŸเบ™เปƒเบ™เบฅเบฐเบซเบงเปˆเบฒเบ‡เบเบฒเบ™เบ”เบตเบšเบฑเบ - เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ™เปเบฒเปƒเบŠเป‰เป€เบ„เบทเปˆเบญเบ‡เบเปเบฒเป€เบ™เบตเบ”เป€เบžเบทเปˆเบญ "เบเบดเบ‡" เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เบ—เบตเปˆเบกเบตเบชเบฑเบ™เบเบฒเบ™เบชเบฝเบ‡.

เบซเบผเบฑเบ‡เบˆเบฒเบเป€เบ„เบทเปˆเบญเบ‡เบเปเบฒเป€เบ™เบตเบ”, เบชเบฑเบ™เบเบฒเบ™เป„เบ›เบซเบฒเบ•เบปเบงเป€เบ‚เบปเป‰เบฒเบฅเบฐเบซเบฑเบ”, เป€เบŠเบดเปˆเบ‡เบ›เปˆเบฝเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡ 16-bit เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบ•เบฒเบกเบกเบฒเบ”เบ•เบฐเบ–เบฒเบ™ ยต-law (G.711) เป€เบ›เบฑเบ™เปเบ›เบ”เบšเบดเบ”. เบขเบนเปˆเบ—เบตเปˆเบœเบปเบ™เบœเบฐเบฅเบดเบ”เบ‚เบญเบ‡เบ•เบปเบงเป€เบ‚เบปเป‰เบฒเบฅเบฐเบซเบฑเบ”, เบžเบงเบเป€เบฎเบปเบฒเบกเบตเบ•เบปเบงเบชเบฐเบเบฑเบ”เบ‚เปเป‰เบกเบนเบ™เป€เบ„เบดเปˆเบ‡เบซเบ™เบถเปˆเบ‡เบ‚เบญเบ‡เบ‚เบฐเบซเบ™เบฒเบ”. เป‚เบ”เบเบ—เบปเปˆเบงเป„เบ›, เบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เบชเบปเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบšเบตเบšเบญเบฑเบ”เบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบ›เบฐเบซเบเบฑเบ”เบเบฒเบ™เบˆเบฐเบฅเบฒเบˆเบญเบ™. เปเบ•เปˆเปƒเบ™เบ—เบตเปˆเบ™เบตเป‰เบกเบฑเบ™เป€เบ›เบฑเบ™เบ›เบฐเป‚เบซเบเบ”เบ—เบตเปˆเบˆเบฐเปƒเบŠเป‰เบ•เบปเบงเป€เบ‚เบปเป‰เบฒเบฅเบฐเบซเบฑเบ”, เป€เบžเบฒเบฐเบงเปˆเบฒ Wireshark เบชเบฒเบกเบฒเบ”เบœเบฐเบฅเบดเบ”เบชเบฝเบ‡เบˆเบฒเบเบเบฐเปเบช RTP เป„เบ”เป‰เบžเบฝเบ‡เปเบ•เปˆเป€เบกเบทเปˆเบญเบกเบฑเบ™เบ–เบทเบเบšเบตเบšเบญเบฑเบ”เบ•เบฒเบก ยต-law เบซเบผเบท a-law.

เบซเบผเบฑเบ‡เบˆเบฒเบเบ•เบปเบงเป€เบ‚เบปเป‰เบฒเบฅเบฐเบซเบฑเบ”, เบ‚เปเป‰เบกเบนเบ™เบชเบฐเบเบฑเบ”เป€เบšเบปเบฒเบเบงเปˆเบฒเบ–เบทเบเบชเบปเปˆเบ‡เป„เบ›เบซเบฒเบ•เบปเบงเบเบญเบ‡ rtpsend, เป€เบŠเบดเปˆเบ‡เบˆเบฐเป€เบฎเบฑเบ”เปƒเบซเป‰เบžเบงเบเป€เบ‚เบปเบฒเบขเบนเปˆเปƒเบ™เบŠเบธเบ” RTP, เบเปเบฒเบ™เบปเบ”เบ—เบธเบ‡เบ—เบตเปˆเบˆเปเบฒเป€เบ›เบฑเบ™เปเบฅเบฐเปƒเบซเป‰เบžเบงเบเป€เบ‚เบปเบฒเบเบฑเบš media streamer เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบชเบปเปˆเบ‡เบœเปˆเบฒเบ™เป€เบ„เบทเบญเบ‚เปˆเบฒเบเปƒเบ™เบฎเบนเบšเปเบšเบšเบ‚เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ” UDP.

เบฅเบฐเบšเบปเบšเบ•เปˆเบญเบ‡เป‚เบชเป‰เป€เบ—เบดเบ‡เบ‚เบญเบ‡เบ•เบปเบงเบเบญเบ‡เบ›เบฐเบเบญเบšเป€เบ›เบฑเบ™เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เบเบฒเบ™เบฎเบฑเบš; เบŠเบธเบ” RTP เบ—เบตเปˆเป„เบ”เป‰เบฎเบฑเบšเป‚เบ”เบ media streamer เบˆเบฒเบเป€เบ„เบทเบญเบ‚เปˆเบฒเบเป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ•เบปเบงเบเบญเบ‡ rtprecv, เบขเบนเปˆเบ—เบตเปˆเบœเบปเบ™เบœเบฐเบฅเบดเบ”เบ—เบตเปˆเบžเบงเบเบกเบฑเบ™เบ›เบฒเบเบปเบ”เบขเบนเปˆเปƒเบ™เบฎเบนเบšเปเบšเบšเบ‚เบญเบ‡เบ‚เปเป‰เบกเบนเบ™, เปเบ•เปˆเบฅเบฐเบญเบฑเบ™เบเบปเบ‡เบเบฑเบšเบŠเบธเบ”เบ—เบตเปˆเป„เบ”เป‰เบฎเบฑเบš. เบšเบฅเบฑเบญเบเบ›เบฐเบเบญเบšเบกเบตเบ‚เปเป‰เบกเบนเบ™ payload เป€เบ—เบปเปˆเบฒเบ™เบฑเป‰เบ™; เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒเบžเบงเบเป€เบ‚เบปเบฒเบ–เบทเบเบชเบฐเปเบ”เบ‡เป€เบ›เบฑเบ™เบชเบตเบ‚เบฝเบงเปƒเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡.

เบ•เปเปˆเป„เบ›, เบ•เบฑเบ™เบ–เบทเบเบชเบปเปˆเบ‡เป„เบ›เบซเบฒเบ•เบปเบงเบเบญเบ‡เบ•เบปเบงเบ–เบญเบ”เบฅเบฐเบซเบฑเบ”, เป€เบŠเบดเปˆเบ‡เบ›เปˆเบฝเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡เบ”เบฝเบงเป„เบšเบ•เปŒเบ—เบตเปˆเบกเบตเบขเบนเปˆเปƒเบ™เบžเบงเบเบกเบฑเบ™เปƒเบซเป‰เป€เบ›เบฑเบ™เป€เบชเบฑเป‰เบ™, 16-เบšเบดเบ”. เป€เบŠเบดเปˆเบ‡เบชเบฒเบกเบฒเบ”เบ›เบฐเบกเบงเบ™เบœเบปเบ™เป„เบ”เป‰เปเบฅเป‰เบงเป‚เบ”เบเบ•เบปเบงเบเบญเบ‡เบเบฐเปเบชเบชเบทเปˆ. เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ, เบžเบงเบเป€เบฎเบปเบฒเบžเบฝเบ‡เปเบ•เปˆเบชเบปเปˆเบ‡เบžเบงเบเบกเบฑเบ™เป„เบ›เบซเบฒเปเบœเปˆเบ™เบชเบฝเบ‡เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบซเบผเบดเป‰เบ™เบขเบนเปˆเปƒเบ™เบฅเปเบฒเป‚เบžเบ‡เบ‚เบญเบ‡เบซเบนเบŸเบฑเบ‡เบ‚เบญเบ‡เบ—เปˆเบฒเบ™.

เบ•เบญเบ™เบ™เบตเป‰เปƒเบซเป‰เป€เบฎเบปเบฒเบเป‰เบฒเบงเป„เบ›เบชเบนเปˆเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบŠเบญเบšเปเบง. เป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เบชเบดเปˆเบ‡เบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบชเบปเบกเบ—เบปเบšเป„เบŸเบฅเปŒเบฎเบฑเบšเปเบฅเบฐเป€เบ„เบทเปˆเบญเบ‡เบชเบปเปˆเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเปเบเบเบญเบญเบเบเปˆเบญเบ™. เบเปˆเบญเบ™เบซเบ™เป‰เบฒเบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เปƒเบŠเป‰เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ„เบปเบ‡เบ—เบตเปˆเบชเปเบฒเบฅเบฑเบšเบžเบญเบ”เปเบฅเบฐเบ—เบตเปˆเบขเบนเปˆ, เปเบ•เปˆเบ•เบญเบ™เบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เป‚เบ›เบผเปเบเบผเบกเป€เบžเบทเปˆเบญเบชเบฒเบกเบฒเบ”เบ™เปเบฒเปƒเบŠเป‰เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบเปเบฒเบ™เบปเบ”เปƒเบ™เบ•เบญเบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™. เป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เบชเบดเปˆเบ‡เบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบžเบตเปˆเบกเบซเบ™เป‰เบฒเบ—เบตเปˆเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ›เบฐเบกเบงเบ™เบœเบปเบ™เบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡เป€เบชเบฑเป‰เบ™เบ„เปเบฒเบชเบฑเปˆเบ‡. เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบชเบฒเบกเบฒเบ”เบเปเบฒเบ™เบปเบ”เบ—เบตเปˆเบขเบนเปˆ IP เปเบฅเบฐเบžเบญเบ”เบ‚เบญเบ‡ intercom เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบชเป‰เบฒเบ‡เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆ.

เบเปˆเบญเบ™เบญเบทเปˆเบ™ เปเบปเบ”, เปƒเบซเป‰เป€เบžเบตเปˆเบกเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เปƒเบซเป‰เบเบฑเบšเป‚เบ›เปเบเบผเบกเบ—เบตเปˆเบˆเบฐเป€เบเบฑเบšเบฎเบฑเบเบชเบฒเบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ‚เบญเบ‡เบกเบฑเบ™:

struct _app_vars
{
  int  local_port;              /* ะ›ะพะบะฐะปัŒะฝั‹ะน ะฟะพั€ั‚. */
  int  remote_port;             /* ะŸะพั€ั‚ ะฟะตั€ะตะณะพะฒะพั€ะฝะพะณะพ ัƒัั‚ั€ะพะนัั‚ะฒะฐ ะฝะฐ ัƒะดะฐะปะตะฝะฝะพะผ ะบะพะผะฟัŒัŽั‚ะตั€ะต. */
  char remote_addr[128];        /* IP-ะฐะดั€ะตั ัƒะดะฐะปะตะฝะฝะพะณะพ ะบะพะผะฟัŒัŽั‚ะตั€ะฐ. */
  MSDtmfGenCustomTone dtmf_cfg; /* ะะฐัั‚ั€ะพะนะบะธ ั‚ะตัั‚ะพะฒะพะณะพ ัะธะณะฝะฐะปะฐ ะณะตะฝะตั€ะฐั‚ะพั€ะฐ. */
};

typedef struct _app_vars app_vars;

เป‚เบ„เบ‡เบเบฒเบ™เบˆเบฐเบ›เบฐเบเบฒเบ”เป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบ‚เบญเบ‡เบ›เบฐเป€เบžเบ”เบ™เบตเป‰เป€เบญเบตเป‰เบ™เบงเปˆเบฒ vars.
เบ•เปเปˆเป„เบ›, เปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเป€เบžเบตเปˆเบกเบŸเบฑเบ‡เบŠเบฑเบ™เป€เบžเบทเปˆเบญเบงเบดเป€เบ„เบฒเบฐเบญเบฒเบเบดเบงเป€เบกเบฑเบ™เปเบ–เบงเบ„เปเบฒเบชเบฑเปˆเบ‡:

/* ะคัƒะฝะบั†ะธั ะฟั€ะตะพะฑั€ะฐะทะพะฒะฐะฝะธั ะฐั€ะณัƒะผะตะฝั‚ะพะฒ ะบะพะผะฐะฝะดะฝะพะน ัั‚ั€ะพะบะธ ะฒ
* ะฝะฐัั‚ั€ะพะนะบะธ ะฟั€ะพะณั€ะฐะผะผั‹. */
void  scan_args(int argc, char *argv[], app_vars *v)
{
    char i;
    for (i=0; i<argc; i++)
    {
        if (!strcmp(argv[i], "--help"))
        {
            char *p=argv[0]; p=p + 2;
            printf("  %s walkie talkienn", p);
            printf("--help      List of options.n");
            printf("--version   Version of application.n");
            printf("--addr      Remote abonent IP address string.n");
            printf("--port      Remote abonent port number.n");
            printf("--lport     Local port number.n");
            printf("--gen       Generator frequency.n");
            exit(0);
        }

        if (!strcmp(argv[i], "--version"))
        {
            printf("0.1n");
            exit(0);
        }

        if (!strcmp(argv[i], "--addr"))
        {
            strncpy(v->remote_addr, argv[i+1], 16);
            v->remote_addr[16]=0;
            printf("remote addr: %sn", v->remote_addr);
        }

        if (!strcmp(argv[i], "--port"))
        {
            v->remote_port=atoi(argv[i+1]);
            printf("remote port: %in", v->remote_port);
        }

        if (!strcmp(argv[i], "--lport"))
        {
            v->local_port=atoi(argv[i+1]);
            printf("local port : %in", v->local_port);
        }

        if (!strcmp(argv[i], "--gen"))
        {
            v -> dtmf_cfg.frequencies[0] = atoi(argv[i+1]);
                printf("gen freq : %in", v -> dtmf_cfg.frequencies[0]);
        }
    }
}

เป€เบ›เบฑเบ™เบœเบปเบ™เบกเบฒเบˆเบฒเบเบเบฒเบ™เปเบเบเบงเบดเป€เบ„เบฒเบฐ, arguments เปเบ–เบงเบ„เปเบฒเบชเบฑเปˆเบ‡เบˆเบฐเบ–เบทเบเบงเบฒเบ‡เป„เบงเป‰เปƒเบ™เบŠเปˆเบญเบ‡เบ‚เปเป‰เบกเบนเบ™เบ‚เบญเบ‡เป‚เบ„เบ‡เบชเป‰เบฒเบ‡ vars. เบซเบ™เป‰เบฒเบ—เบตเปˆเบ•เบปเป‰เบ™เบ•เปเบ‚เบญเบ‡เบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบเปเบกเปˆเบ™เป€เบžเบทเปˆเบญเป€เบเบฑเบšเบเปเบฒเบเบฒเบ™เบชเบปเปˆเบ‡เปเบฅเบฐเบเบฒเบ™เบฎเบฑเบšเป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เบˆเบฒเบเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡; เบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆ ticker, เบเบฒเบ™เบ„เบงเบšเบ„เบธเบกเบˆเบฐเบ–เบทเบเป‚เบญเบ™เป„เบ›เป€เบ›เบฑเบ™ loop infinite เป€เบŠเบดเปˆเบ‡, เบ–เป‰เบฒเบ„เบงเบฒเบกเบ–เบตเปˆเบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบเปเบฒเป€เบ™เบตเบ”เป„เบŸเบŸเป‰เบฒเบ–เบทเบเบ•เบฑเป‰เบ‡เป€เบ›เบฑเบ™เบšเปเปˆเปเบกเปˆเบ™เบชเบนเบ™, เบˆเบฐ restart เป€เบ„เบทเปˆเบญเบ‡เบเปเบฒเป€เบ™เบตเบ”เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเป€เบžเบทเปˆเบญเบงเปˆเบฒ. เบกเบฑเบ™เป€เบฎเบฑเบ”เบงเบฝเบเป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบขเบธเบ”.

เป€เบ„เบทเปˆเบญเบ‡เบเปเบฒเป€เบ™เบตเบ”เป„เบŸเบŸเป‰เบฒเบˆเบฐเบ•เป‰เบญเบ‡เบเบฒเบ™เบเบฒเบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เปƒเบซเบกเปˆเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบเบฒเบ™เบญเบญเบเปเบšเบšเบ‚เบญเบ‡เบกเบฑเบ™; เบชเปเบฒเบฅเบฑเบšเป€เบซเบ”เบœเบปเบ™เบšเบฒเบ‡เบขเปˆเบฒเบ‡เบกเบฑเบ™เบšเปเปˆเบชเบฒเบกเบฒเบ”เบชเป‰เบฒเบ‡เบชเบฑเบ™เบเบฒเบ™เบ—เบตเปˆเบเบฒเบงเบเบงเปˆเบฒ 16 เบงเบดเบ™เบฒเบ—เบต. เบกเบฑเบ™เบ„เบงเบ™เบˆเบฐเบชเบฑเบ‡เป€เบเบ”เบงเปˆเบฒเป„เบฅเบเบฐเป€เบงเบฅเบฒเบ‚เบญเบ‡เบกเบฑเบ™เบ–เบทเบเบฅเบฐเบšเบธเป„เบงเป‰เป‚เบ”เบเบ•เบปเบงเป€เบฅเบ 32-bit.

เป‚เบ„เบ‡โ€‹เบเบฒเบ™โ€‹เบ—เบฑเบ‡โ€‹เบซเบกเบปเบ”โ€‹เบˆเบฐโ€‹เป€เบ›เบฑเบ™โ€‹เบ”เบฑเปˆเบ‡โ€‹เบ™เบตเป‰โ€‹:

/* ะคะฐะนะป mstest8.c ะ˜ะผะธั‚ะฐั‚ะพั€ ะฟะตั€ะตะณะพะฒะพั€ะฝะพะณะพ ัƒัั‚ั€ะพะนัั‚ะฒะฐ. */

#include <mediastreamer2/mssndcard.h>
#include <mediastreamer2/dtmfgen.h>
#include <mediastreamer2/msrtp.h>

/* ะŸะพะดะบะปัŽั‡ะฐะตะผ ั„ะฐะนะป ะพะฑั‰ะธั… ั„ัƒะฝะบั†ะธะน. */
#include "mstest_common.c"

/*----------------------------------------------------------*/
struct _app_vars
{
    int  local_port;              /* ะ›ะพะบะฐะปัŒะฝั‹ะน ะฟะพั€ั‚. */
    int  remote_port;             /* ะŸะพั€ั‚ ะฟะตั€ะตะณะพะฒะพั€ะฝะพะณะพ ัƒัั‚ั€ะพะนัั‚ะฒะฐ ะฝะฐ ัƒะดะฐะปะตะฝะฝะพะผ ะบะพะผะฟัŒัŽั‚ะตั€ะต. */
    char remote_addr[128];        /* IP-ะฐะดั€ะตั ัƒะดะฐะปะตะฝะฝะพะณะพ ะบะพะผะฟัŒัŽั‚ะตั€ะฐ. */
    MSDtmfGenCustomTone dtmf_cfg; /* ะะฐัั‚ั€ะพะนะบะธ ั‚ะตัั‚ะพะฒะพะณะพ ัะธะณะฝะฐะปะฐ ะณะตะฝะตั€ะฐั‚ะพั€ะฐ. */
};

typedef struct _app_vars app_vars;

/*----------------------------------------------------------*/
/* ะกะพะทะดะฐะตะผ ะดัƒะฟะปะตะบัะฝัƒัŽ RTP-ัะตััะธัŽ. */
RtpSession* create_duplex_rtp_session(app_vars v)
{
    RtpSession *session = create_rtpsession (v.local_port, v.local_port + 1, FALSE, RTP_SESSION_SENDRECV);
    rtp_session_set_remote_addr_and_port(session, v.remote_addr, v.remote_port, v.remote_port + 1);
    rtp_session_set_send_payload_type(session, PCMU);
    return session;
}

/*----------------------------------------------------------*/
/* ะคัƒะฝะบั†ะธั ะฟั€ะตะพะฑั€ะฐะทะพะฒะฐะฝะธั ะฐั€ะณัƒะผะตะฝั‚ะพะฒ ะบะพะผะฐะฝะดะฝะพะน ัั‚ั€ะพะบะธ ะฒ
* ะฝะฐัั‚ั€ะพะนะบะธ ะฟั€ะพะณั€ะฐะผะผั‹. */
void  scan_args(int argc, char *argv[], app_vars *v)
{
    char i;
    for (i=0; i<argc; i++)
    {
        if (!strcmp(argv[i], "--help"))
        {
            char *p=argv[0]; p=p + 2;
            printf("  %s walkie talkienn", p);
            printf("--help      List of options.n");
            printf("--version   Version of application.n");
            printf("--addr      Remote abonent IP address string.n");
            printf("--port      Remote abonent port number.n");
            printf("--lport     Local port number.n");
            printf("--gen       Generator frequency.n");
            exit(0);
        }

        if (!strcmp(argv[i], "--version"))
        {
            printf("0.1n");
            exit(0);
        }

        if (!strcmp(argv[i], "--addr"))
        {
            strncpy(v->remote_addr, argv[i+1], 16);
            v->remote_addr[16]=0;
            printf("remote addr: %sn", v->remote_addr);
        }

        if (!strcmp(argv[i], "--port"))
        {
            v->remote_port=atoi(argv[i+1]);
            printf("remote port: %in", v->remote_port);
        }

        if (!strcmp(argv[i], "--lport"))
        {
            v->local_port=atoi(argv[i+1]);
            printf("local port : %in", v->local_port);
        }

        if (!strcmp(argv[i], "--gen"))
        {
            v -> dtmf_cfg.frequencies[0] = atoi(argv[i+1]);
                printf("gen freq : %in", v -> dtmf_cfg.frequencies[0]);
        }
    }
}

/*----------------------------------------------------------*/
int main(int argc, char *argv[])
{
    /* ะฃัั‚ะฐะฝะฐะฒะปะธะฒะฐะตะผ ะฝะฐัั‚ั€ะพะนะบะธ ะฟะพ ัƒะผะพะปั‡ะฐะฝะธัŽ. */
    app_vars vars={5004, 7010, "127.0.0.1", {0}};

    /* ะฃัั‚ะฐะฝะฐะฒะปะธะฒะฐะตะผ ะฝะฐัั‚ั€ะพะนะบะธ ะฝะฐัั‚ั€ะพะนะบะธ ะฟั€ะพะณั€ะฐะผะผั‹ ะฒ
     * ัะพะพั‚ะฒะตั‚ัั‚ะฒะธะธ ั ะฐั€ะณัƒะผะตะฝั‚ะฐะผะธ ะบะพะผะฐะฝะดะฝะพะน ัั‚ั€ะพะบะธ. */
    scan_args(argc, argv, &vars);

    ms_init();

    /* ะกะพะทะดะฐะตะผ ัะบะทะตะผะฟะปัั€ั‹ ั„ะธะปัŒั‚ั€ะพะฒ ะฟะตั€ะตะดะฐัŽั‰ะตะณะพ ั‚ั€ะฐะบั‚ะฐ. */
    MSSndCard *snd_card =
        ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
    MSFilter *snd_card_read = ms_snd_card_create_reader(snd_card);
    MSFilter *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);
    MSFilter *rtpsend = ms_filter_new(MS_RTP_SEND_ID);

    /* ะกะพะทะดะฐะตะผ ั„ะธะปัŒั‚ั€ ะบะพะดะตั€ะฐ. */
    MSFilter *encoder = ms_filter_create_encoder("PCMU");

    /* ะ ะตะณะธัั‚ั€ะธั€ัƒะตะผ ั‚ะธะฟั‹ ะฝะฐะณั€ัƒะทะบะธ. */
    register_payloads();

    /* ะกะพะทะดะฐะตะผ ะดัƒะฟะปะตะบัะฝัƒัŽ RTP-ัะตััะธัŽ. */
    RtpSession* rtp_session= create_duplex_rtp_session(vars);
    ms_filter_call_method(rtpsend, MS_RTP_SEND_SET_SESSION, rtp_session);

    /* ะกะพะตะดะธะฝัะตะผ ั„ะธะปัŒั‚ั€ั‹ ะฟะตั€ะตะดะฐั‚ั‡ะธะบะฐ. */
    ms_filter_link(snd_card_read, 0, dtmfgen, 0);
    ms_filter_link(dtmfgen, 0, encoder, 0);
    ms_filter_link(encoder, 0, rtpsend, 0);

    /* ะกะพะทะดะฐะตะผ ั„ะธะปัŒั‚ั€ั‹ ะฟั€ะธะตะผะฝะพะณะพ ั‚ั€ะฐะบั‚ะฐ. */
    MSFilter *rtprecv = ms_filter_new(MS_RTP_RECV_ID);
    ms_filter_call_method(rtprecv, MS_RTP_RECV_SET_SESSION, rtp_session);

    /* ะกะพะทะดะฐะตะผ ั„ะธะปัŒั‚ั€ ะดะตะบะพะดะตั€ะฐ, */
    MSFilter *decoder=ms_filter_create_decoder("PCMU");

    /* ะกะพะทะดะฐะตะผ ั„ะธะปัŒั‚ั€ ะทะฒัƒะบะพะฒะพะน ะบะฐั€ั‚ั‹. */
    MSFilter *snd_card_write = ms_snd_card_create_writer(snd_card);

    /* ะกะพะตะดะธะฝัะตะผ ั„ะธะปัŒั‚ั€ั‹ ะฟั€ะธั‘ะผะฝะพะณะพ ั‚ั€ะฐะบั‚ะฐ. */
    ms_filter_link(rtprecv, 0, decoder, 0);
    ms_filter_link(decoder, 0,  snd_card_write, 0);

    /* ะกะพะทะดะฐะตะผ ะธัั‚ะพั‡ะฝะธะบ ั‚ะฐะบั‚ะพะฒ - ั‚ะธะบะตั€. */
    MSTicker *ticker = ms_ticker_new();

    /* ะŸะพะดะบะปัŽั‡ะฐะตะผ ะธัั‚ะพั‡ะฝะธะบ ั‚ะฐะบั‚ะพะฒ. */
    ms_ticker_attach(ticker, snd_card_read);
    ms_ticker_attach(ticker, rtprecv);

    /* ะ•ัะปะธ ะฝะฐัั‚ั€ะพะนะบะฐ ั‡ะฐัั‚ะพั‚ั‹ ะณะตะฝะตั€ะฐั‚ะพั€ะฐ ะพั‚ะปะธั‡ะฝะฐ ะพั‚ ะฝัƒะปั, ั‚ะพ ะทะฐะฟัƒัะบะฐะตะผ ะณะตะฝะตั€ะฐั‚ะพั€. */   
    if (vars.dtmf_cfg.frequencies[0])
    {
        /* ะะฐัั‚ั€ะฐะธะฒะฐะตะผ ัั‚ั€ัƒะบั‚ัƒั€ัƒ, ัƒะฟั€ะฐะฒะปััŽั‰ัƒัŽ ะฒั‹ั…ะพะดะฝั‹ะผ ัะธะณะฝะฐะปะพะผ ะณะตะฝะตั€ะฐั‚ะพั€ะฐ. */
        vars.dtmf_cfg.duration = 10000;
        vars.dtmf_cfg.amplitude = 1.0;
    }

    /* ะžั€ะณะฐะฝะธะทัƒะตะผ ั†ะธะบะป ะฟะตั€ะตะทะฐะฟัƒัะบะฐ ะณะตะฝะตั€ะฐั‚ะพั€ะฐ. */
    while(TRUE)
    {
        if(vars.dtmf_cfg.frequencies[0])
        {
            /* ะ’ะบะปัŽั‡ะฐะตะผ ะทะฒัƒะบะพะฒะพะน ะณะตะฝะตั€ะฐั‚ะพั€. */
            ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY_CUSTOM,
                    (void*)&vars.dtmf_cfg);
        }
        /* ะฃะบะปะฐะดั‹ะฒะฐะตะผ ั‚ั€ะตะด ะฒ ัะฟัั‡ะบัƒ ะฝะฐ 20ะผั, ั‡ั‚ะพะฑั‹ ะดั€ัƒะณะธะต ั‚ั€ะตะดั‹
         * ะฟั€ะธะปะพะถะตะฝะธั ะฟะพะปัƒั‡ะธะปะธ ะฒั€ะตะผั ะฝะฐ ั€ะฐะฑะพั‚ัƒ. */
        ms_usleep(20000);
    }
}

เปƒเบซเป‰เบฅเบงเบšเบฅเบงเบก. เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เป‚เบ„เบ‡เบเบฒเบ™เบชเบฒเบกเบฒเบ”เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เปƒเบ™เบชเบญเบ‡เบ„เบญเบกเบžเบดเบงเป€เบ•เบต. เบซเบผเบทเบซเบ™เบถเปˆเบ‡, เบ”เบฑเปˆเบ‡เบ—เบตเปˆเบ‚เป‰เบญเบเบˆเบฐเป€เบฎเบฑเบ”เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™. เบžเบงเบเป€เบฎเบปเบฒเป€เบ›เบตเบ”เบ•เบปเบง TShark เบ”เป‰เบงเบเบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡เบ•เปเปˆเป„เบ›เบ™เบตเป‰:

$ sudo tshark -i lo -f "udp dst port 7010" -P -V -O RTP -o rtp.heuristic_rtp:TRUE -x

เบ–เป‰เบฒเบžเบฒเบเบชเบฐเบซเบ™เบฒเบกเป€เบ›เบตเบ”เบ•เบปเบงเปƒเบ™ console เบžเบฝเบ‡เปเบ•เปˆเบชเบฐเปเบ”เบ‡เบ‚เปเป‰เบ„เบงเบฒเบกเบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ‚เบญเบ‡เบเบฒเบ™เบˆเบฑเบšเบžเบฒเบš, เบ™เบตเป‰เปเบกเปˆเบ™เบชเบฑเบ™เบเบฒเบ™เบ—เบตเปˆเบ”เบต - เบกเบฑเบ™เบซเบกเบฒเบเบ„เบงเบฒเบกเบงเปˆเบฒเบžเบญเบ”เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบชเปˆเบงเบ™เบซเบผเบฒเบเบˆเบฐเบšเปเปˆเบ–เบทเบเบ„เบญเบšเบ„เบญเบ‡เป‚เบ”เบเป‚เบ„เบ‡เบเบฒเบ™เบญเบทเปˆเบ™เป†. เบขเบนเปˆเปƒเบ™เบชเบฐเบ–เบฒเบ™เบตเบญเบทเปˆเบ™, เบžเบงเบเป€เบฎเบปเบฒเป€เบ›เบตเบ”เบ•เบปเบงเบขเปˆเบฒเบ‡เป‚เบ„เบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบˆเปเบฒเบฅเบญเบ‡ "เป„เบฅเบเบฐเป„เบ" intercom เป‚เบ”เบเบเบฒเบ™เบฅเบฐเบšเบธเบซเบกเบฒเบเป€เบฅเบเบžเบญเบ”เบ™เบตเป‰:

$ ./mstest8 --port 9010 --lport 7010

เบ”เบฑเปˆเบ‡เบ—เบตเปˆเป€เบซเบฑเบ™เป„เบ”เป‰เบˆเบฒเบเบ‚เปเป‰เบ„เบงเบฒเบกเบ‚เบญเบ‡เป‚เบ›เบฃเปเบเบฃเบก, เบ—เบตเปˆเบขเบนเปˆ IP เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เปเบกเปˆเบ™ 127.0.0.1 (local loopback).

เบขเบนเปˆเปƒเบ™เบชเบฐเบ–เบฒเบ™เบตเบญเบทเปˆเบ™, เบžเบงเบเป€เบฎเบปเบฒเป€เบ›เบตเบ”เบ•เบปเบงเบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเบชเบญเบ‡เบ‚เบญเบ‡เป‚เบ„เบ‡เบเบฒเบ™, เป€เบŠเบดเปˆเบ‡เบˆเปเบฒเบฅเบญเบ‡เบญเบธเบ›เบฐเบเบญเบ™เบ—เป‰เบญเบ‡เบ–เบดเปˆเบ™. เบžเบงเบเป€เบฎเบปเบฒเปƒเบŠเป‰เบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบ—เบตเปˆเบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เป€เบ„เบทเปˆเบญเบ‡เบเปเบฒเป€เบ™เบตเบ”เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเปƒเบ™เบ•เบปเบงเบชเบฒเบกเบฒเบ”เป€เบฎเบฑเบ”เบงเบฝเบเป„เบ”เป‰:

$ ./mstest8  --port 7010 --lport 9010 --gen 440

เปƒเบ™เป€เบงเบฅเบฒเบ™เบตเป‰, เปเบžเบฑเบเป€เบเบฑเบ”เบ—เบตเปˆเบ–เบทเบเบชเบปเปˆเบ‡เป„เบ›เบซเบฒเบญเบธเบ›เบฐเบเบญเบ™ "เป„เบฅเบเบฐเป„เบ" เบ„เบงเบ™เป€เบฅเบตเปˆเบกเบเบฐเบžเบดเบšเปƒเบ™เบ„เบญเบ™เป‚เบŠเบ™เบ”เป‰เบงเบ TShark, เปเบฅเบฐเบชเบฝเบ‡เบขเปˆเบฒเบ‡เบ•เปเปˆเป€เบ™เบทเปˆเบญเบ‡เบˆเบฐเป„เบ”เป‰เบเบดเบ™เบˆเบฒเบเบฅเปเบฒเป‚เบžเบ‡เบ„เบญเบกเบžเบดเบงเป€เบ•เบต.

เบ–เป‰เบฒเบ—เบธเบเบชเบดเปˆเบ‡เบ—เบธเบเบขเปˆเบฒเบ‡เป€เบเบตเบ”เบ‚เบถเป‰เบ™เบ•เบฒเบกเบ—เบตเปˆเบ‚เบฝเบ™, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบžเบงเบเป€เบฎเบปเบฒเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบชเปเบฒเป€เบ™เบปเบฒเบ—เบตเบชเบญเบ‡เบ‚เบญเบ‡เป‚เบ„เบ‡เบเบฒเบ™, เปเบ•เปˆเบšเปเปˆเบกเบตเบฅเบฐเบซเบฑเบ”เปเบฅเบฐเบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡ "โ€”gen 440". เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบ—เปˆเบฒเบ™เบˆเบฐเบซเบฅเบดเป‰เบ™เบšเบปเบ”เบšเบฒเบ”เบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบเปเบฒเป€เบ™เบตเบ”เป„เบŸเบŸเป‰เบฒ. เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบตเป‰, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบชเป‰เบฒเบ‡เบชเบดเปˆเบ‡เบฅเบปเบšเบเบงเบ™เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เป„เบกเป‚เบ„เบฃเป‚เบŸเบ™เป„เบ”เป‰; เบ—เปˆเบฒเบ™เบ„เบงเบ™เป„เบ”เป‰เบเบดเบ™เบชเบฝเบ‡เบ—เบตเปˆเบชเบญเบ”เบ„เป‰เบญเบ‡เบเบฑเบ™เบขเบนเปˆเปƒเบ™เบฅเปเบฒเป‚เบžเบ‡เบซเบผเบทเบซเบนเบŸเบฑเบ‡. เบ„เบงเบฒเบกเบ•เบทเปˆเบ™เป€เบ•เบฑเป‰เบ™เบ‚เบญเบ‡เบ•เบปเบ™เป€เบญเบ‡เบญเบฒเบ”เป€เบเบตเบ”เบ‚เบถเป‰เบ™เป„เบ”เป‰; เบ›เบดเบ”เบชเบฝเบ‡เบฅเบณเป‚เบžเบ‡เบฅเบปเบ‡ เปเบฅเป‰เบงเป€เบญเบฑเบšเป€เบŸเบฑเบเบˆเบฐเบซเบฒเบเป„เบ›.

เบ–เป‰เบฒเบ—เปˆเบฒเบ™เปเบฅเปˆเบ™เบกเบฑเบ™เบขเบนเปˆเปƒเบ™เบชเบญเบ‡เบ„เบญเบกเบžเบดเบงเป€เบ•เบตเปเบฅเบฐเบšเปเปˆเบชเบฑเบšเบชเบปเบ™เบเปˆเบฝเบงเบเบฑเบšเบ—เบตเปˆเบขเบนเปˆ IP, เบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบšเบ”เบฝเบงเบเบฑเบ™เบฅเปเบ–เป‰เบฒเบ—เปˆเบฒเบ™ - เบเบฒเบ™เบชเบทเปˆเบชเบฒเบ™เบชเบฝเบ‡เบ—เบตเปˆเบกเบตเบ„เบธเบ™เบ™เบฐเบžเบฒเบšเบ”เบตเบˆเบตเบ•เบญเบ™เบชเบญเบ‡เบ—เบฒเบ‡.

เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ•เปเปˆเป„เบ›เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบฎเบฝเบ™เบฎเบนเป‰เบงเบดเบ—เบตเบเบฒเบ™เบ‚เบฝเบ™เบ•เบปเบงเบเบญเบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเป€เบญเบ‡ - plugins, เบ‚เปเบ‚เบญเบšเปƒเบˆเบเบฑเบšเบ—เบฑเบเบชเบฐเบ™เบตเป‰, เบ—เปˆเบฒเบ™เบˆเบฐเบชเบฒเบกเบฒเบ”เบ™เปเบฒเปƒเบŠเป‰ media streamer เบšเปเปˆเบžเบฝเบ‡เปเบ•เปˆเบชเปเบฒเบฅเบฑเบšเบชเบฝเบ‡เปเบฅเบฐเบงเบดเบ”เบตเป‚เบญ, เปเบ•เปˆเบเบฑเบ‡เบขเบนเปˆเปƒเบ™เบšเบฒเบ‡เบžเบทเป‰เบ™เบ—เบตเปˆเบชเบฐเป€เบžเบฒเบฐเบญเบทเปˆเบ™เป†.

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™