рд╣рдо рдХреИрдорд░реЗ рд╕реЗ рд╡реАрдбрд┐рдпреЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП DVR рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ PHP рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ

рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВрдиреЗ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджрд┐рдЦрд╛рдиреЗ рдХрд╛ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ рдерд╛ рдЬреЛ рдХреИрдорд░реЗ рд╕реЗ рд╡реАрдбрд┐рдпреЛ рдЦреАрдВрдЪрддреА рд╣реИ рдФрд░, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдордп рдмреАрдд рдЪреБрдХрд╛ рд╣реИ, рд╡рд╛рджреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рдореИрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

рдпрд╣ рд╕рд┐рд░реНрдл рдЗрддрдирд╛ рд╣реБрдЖ рдХрд┐ рд╕рд░реНрд╡рд░ рд╡реЗрдм рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХрддрд╛ рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рд▓реЗрдХрд┐рди PHP рдирд╣реАрдВред

рдареАрдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐, рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдпрд╣ рдорд░рдиреЗ рд╡рд╛рд▓рд╛ рдореЙрдбрд▓, рдореЗрдореЛрд░реА рд▓реАрдХ, рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ PHP рдореЗрдВ рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ рд╕рд┐рд╡рд╛рдп stream_select () рдФрд░ stream_set_blocking () рдХреЗ ред

рдХрд╣реАрдВ рди рдХрд╣реАрдВ, PECL рдкрд░, рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреА рд▓рд┐рдмреНрдпреВ рд╣реИ , рдЬреЛ рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ рдореВрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдореВрд▓ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд┐рд░реНрдл рдПрдХ рдЖрд╡рд░рдг рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЖрдкрдХреЛ рдХреБрдЫ рдЪреБрдиреМрддрд┐рдпрд╛рдВ рджреЗрддрд╛ рд╣реИред рд╡реИрд╕реЗ рднреА, рдЙрдирдХреЗ рд╕рд╣реА рджрд┐рдорд╛рдЧ рдореЗрдВ рдХреМрди рдРрд╕рд╛ рдХрд░реЗрдЧрд╛?

рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣рдо PHP4 рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рд░рд╣рдирд╛ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдЖрдзреБрдирд┐рдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛рдУрдВ рдореЗрдВ рдереЛрдбрд╝рд╛ рд▓реМрдЯрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рд╣рд╛рд▓ рдХреЗ рд╡рд░реНрд╖реЛрдВ рдореЗрдВ рдЪреАрдЬреЗрдВ рдХреБрдЫ рд╣рдж рддрдХ рдмрджрд▓ рдЧрдИ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ ReactPHP рдФрд░ AmPHP рдЬреИрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдЙрдкрдХрд░рдг рд╣реИрдВ, рдЬрд┐рдирдХреЗ рдШрдЯрдХ Node.js рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╡рд░ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЬрдирд░реЗрдЯрд░ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╣рдореЗрдВ async / рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреА рддрд░рд╣ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╢реИрд▓реА рдореЗрдВ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ, рдХреЙрд▓рдмреИрдХ рдФрд░ рдХрд┐рд▓реЛрдореАрдЯрд░ рдЪреЗрди рдореЗрдВ рд╕рднреА рдЕрдВрддрд╣реАрди рдХреЙрд▓рдмреИрдХ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдПред )ред рддрдм () рддрдм () ред

рддреЛ рдЕрдм рдРрд╕рд╛ рдХреНрдпреЛрдВ рд╣реИ, рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, Node.js рдХреА рджреБрдирд┐рдпрд╛ рд╕реЗ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдХреЛрдИ рдХрд╛рд░реНрдп рдирд╣реАрдВ рд╣реИ рдЬреЛ PHP рд╣рд▓ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЕрднреА рднреА рдХреБрдЫ рд╣реИрдВ, рддреЛ рд╕рдм рдХреБрдЫ рдХреЗрд╡рд▓ рдХреБрдЫ рдЕрд▓рдЧ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рди рдХрд┐ рдЕрд╡рд╕рд░реЛрдВ рдХреА рдХрдореАред
рд▓реЛрдЧреЛрдВ рдХреЛ рдпрд╣ рдЬрд╛рдирдХрд░ рдЖрд╢реНрдЪрд░реНрдп рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ PHP рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдм рдХреБрдЫ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдЗрд╡реЗрдВрдЯ-рд╕рдВрдЪрд╛рд▓рд┐рдд рдФрд░ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдо рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдХреЗрд╡рд▓ рдореВрд▓ PHP рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреА рд╕реАрдорд╛ рддрдХ рдкрд╣реБрдБрдЪрддреЗ рд╣реИрдВ рдЬрдм рд╣рдо рдЗрд╕реЗ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ IO рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рд╣рдЬрд╛рд░реЛрдВ рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЗ рд╕рд░реНрд╡реЗрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХрд╣рддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рднреА, рд╣рд╛рд▓рд╛рдВрдХрд┐ рджреЛрд╖ PHP рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд╕рд┐рд╕реНрдЯрдо рдЪрдпрди () рдХреЙрд▓ рдЬреЛ рд▓реЛрдб рдмрдврд╝рдиреЗ рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдЧрд┐рд░рд╛рд╡рдЯ рдореЗрдВ рд░реИрдЦрд┐рдХ рд╣реИред

amphp.org/amp/event-loop

рдмреЗрд╢рдХ, рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдЗрд╕ рд╕рдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕рд╡рд╛рд▓ рдЕрднреА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмрдВрдж рдирд╣реАрдВ рд╣реБрдЖ рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЧрд▓рдд рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ рдХреЛрдИ рдЕрдиреНрдп рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░рдирдЯрд╛рдЗрдо рд╡рд╛рддрд╛рд╡рд░рдг рдЖрдкрдХреЛ рдорд╛рдл рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рддреЛ рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

DVRIP


рд╣рдо рдЪреАрдиреА рджреНрд╡рд╛рд░рд╛ рдХрдерд┐рдд рддреМрд░ рдкрд░ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд┐рдП рдЧрдП рдПрдХ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рдЧрд░рд╛рдиреА рдХреИрдорд░реЛрдВ рдХреЗ рд╕рд╛рде рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдХреЛ рд╕рдВрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдпрд╣ рд╕рднреА TCP рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ DVRIP (рдХрднреА-рдХрднреА рд╕реЛрдлрд┐рдпрд╛) рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЬрдм рддрдХ рдореБрдЭреЗ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддрдм рддрдХ рдореБрдЭреЗ рдХреЗрд╡рд▓ рджреЛ рдпрд╛ рдЕрдзрд┐рдХ рд╕реЗрдВрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдорд┐рд▓реАрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рдЖрдорддреМрд░ рдкрд░ рдХреЗрд╡рд▓ рдХреИрдорд░реЗ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдФрд░ рдХреБрдЫ рд╕рдВрджреЗрд╢реЛрдВ рдХрд╛ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдкреИрдХреЗрдЬ рд╣реЗрдбрд░ рд╡рд┐рд╡рд░рдг рдЬрд┐рд╕рдиреЗ рдореБрдЭреЗ рдмрд╣реБрдд рдорджрдж рдХреАред

рджреВрд╕рд░реЗ рдХреЛ рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рдкрд╛рдпрд╛ рдЧрдпрд╛, рдПрдХреНрд╕рд░реНрд╕рд╛рдЗрдЬ рдХреЗ рд╕рдордп рдореЗрд░реЗ рд╕рд┐рдВрдбреНрд░реЛрдо рдХрд╛ рдпрд╣рд╛рдВ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдирд╣реАрдВ рд╣реБрдЖ рдерд╛, рдФрд░ рдЗрд╕рдиреЗ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдЬреЛ рдореБрдЭреЗ рдкрд╕рдВрдж рдЖрдПрдЧрд╛ред

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдПрдХ рд╕реНрдирд┐рдлрд╝рд░ рдФрд░ рдкреИрдХреЗрдЬ рд╣реЗрдбрд░ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде рд╕рд╢рд╕реНрддреНрд░, рдореИрдВрдиреЗ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд╕реНрдХреЗрдЪ рдХрд┐рдпрд╛ рдЬреЛ рдореЗрд░реЗ рд╕рд░реНрд╡рд░ рдкрд░ рдХрд╣реАрдВ рди рдХрд╣реАрдВ рдШреВрдо рд░рд╣рд╛ рд╣реИ, рдФрд░ рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЗ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдорд╛рдг рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рд╕реНрд╡рдпрдВ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд╣реИ рдФрд░ рдкреИрдХреЗрдЬ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

  • 20 рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рд╣реЗрдбрд░, рдЬреЛ PHP рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ

    unpack('Chead/Cversion/x2/IsessionId/Isequence/x2/SmsgId/Ilen', $buffer) 
  • рд╣реЗрдбрд░ рдПрдХ рд▓рдВрдмреЗ рд▓реЗрди рд╕рдВрджреЗрд╢ рдХреЗ рдмрд╛рдж рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рджреЛ рдмрд╛рдЗрдЯреНрд╕ \ x0a \ x00, рдпрд╛ рдмрд╛рдЗрдирд░реА рдбреЗрдЯрд╛ рджреНрд╡рд╛рд░рд╛ рдкреВрд░рдХ рдпрд╛ рддреЛ рдЬрд╕рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рд╣рдо рдХреЗрд╡рд▓ рдЬрд╕рди рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рд╣рдо рджреЛрдиреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗред

рдЙрддреНрддрд░ (рдпрджрд┐ рдпрд╣ рдПрдХ рдкреИрдХреЗрдЬ рд╣реИ рдЬреЛ рдХрд┐ рдЬреМрди рдХреЗ рд╕рд╛рде рд╣реИ) рдЖрдорддреМрд░ рдкрд░ рд╣рдорд╛рд░реЗ рдЕрдиреБрд░реЛрдз рдХреА рд╕рдлрд▓рддрд╛ рдХрд╛ рд╕рдВрдХреЗрдд рджреЗрдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рд░рд┐рдЯ рдлреАрд▓реНрдб рд╣реЛрддрд╛ рд╣реИред рдПрдХ рд░рд┐рдЯ рдХреЛрдб рдпреБрдХреНрдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдПрдВ рдЬреЛ 100 рдпрд╛ 515 рдХреЗ рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рдЬрд╛рдирдмреВрдЭрдХрд░ рдЧрд▓рдд рдорд╛рдирд╛ рдЬрд╛рдПрдЧрд╛ред

рдЗрд╕ рдмреБрдирд┐рдпрд╛рджреА рдЬреНрдЮрд╛рди рдХреЗ рд╕рд╛рде, рдЪрд▓реЛ рдХреИрдорд░реЗ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ рдФрд░ рд╕рдордЭреЗрдВред
рд╣рдореЗрдВ рджреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ - рдПрдореНрдлрд╝рдкреА / рд╕реЙрдХреЗрдЯ , рдЬреЛ рд╣рдореЗрдВ рдЬрд╝рд░реВрд░рдд рдХреА рд▓рдЧрднрдЧ рд╣рд░ рдЪреАрдЬрд╝ рдХреЛ рдЦреАрдВрдЪ рд▓реЗрдЧрд╛, рдФрд░ рд╢рд╛рдо / рд╢рд╛рдо , рдЬреЛ рдХрд┐ рдкреИрдХрдЧрд┐рд╕реНрдЯ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ рдФрд░ рдХрд┐рд╕реА рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

Amp рдореЗрдВ TCP рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реИ:

 Loop::run(function () { $socket = yield connect("tcp://{$addr}:{$port}"); yield $socket->write('Hello'); while ($chunk = yield $socket->read()) { echo $chunk; } $socket->close(); }); 

DVRIP рдЖрдорддреМрд░ рдкрд░ 34567 рдкреЛрд░реНрдЯ рдкрд░ рдЪрд▓рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:

 $socket = yield connect('tcp://192.168.0.200:34567'); 

рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдЕрдкрдиреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо рдФрд░ рдкрд╛рд╕рд╡рд░реНрдб рд╣реИрд╢ рдХреЛ рдХреИрдорд░реЗ рдореЗрдВ рднреЗрдЬрдХрд░ рд▓реЙрдЧ рдЗрди рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреА рдЧрдгрдирд╛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ:

 function sofiaHash(string $password) : string { $md5 = md5($password, true); return implode('', array_map(function ($i) use ($md5) { $c = (ord($md5[2 * $i]) + ord($md5[2 * $i + 1])) % 62; $c += $c > 9 ? ($c > 35 ? 61 : 55) : 48; return chr($c); }, range(0, 7))); } 

рд╕рдлрд▓ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдПрдХ рд╡реАрдбрд┐рдпреЛ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ рдФрд░, рдЕрдЧрд░ рдХреИрдорд░рд╛ рд╣рдореЗрдВ рджреЗ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред

рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрдХреЗрдЬ рдХрд╛ рдЕрдкрдирд╛ msgId рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдХрд┐рд╕ рдЕрдиреБрд░реЛрдз рдХрд╛ рдЬрд╡рд╛рдм рдорд┐рд▓рд╛ред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдзреВрд▓ рднрд░реА рдиреМрдХрд░реА рдирд╣реАрдВред

рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдкрд╣рд▓реЗ рд╣рдорд╛рд░реЗ рдкреИрдХреЗрдЬ рдХреЗ рд▓рд┐рдП рдХрдХреНрд╖рд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ:

 class Packet { public const SUCCESS_CODES = [100, 515]; public const MESSAGE_CODES = [ 'packet.request.login' => 1000, 'packet.request.keepAlive' => 1006, 'packet.request.claim' => 1413, 'packet.response.login' => 1001, 'packet.response.keepAlive' => 1007, 'packet.response.claim' => 1414, 'packet.videoControl' => 1410, 'packet.binary' => 1412, ]; protected int $head = 255; protected int $version = 0; protected int $sessionId; protected int $sequence; protected int $msgId; protected ?string $rawData; protected ?array $data; public function __construct(int $msgId, ?array $data = null, int $sequence = 0, int $sessionId = 0) { $this->msgId = $msgId; $this->data = $data; $this->sequence = $sequence; $this->sessionId = $sessionId; } public function __toString() : string { if ($this->data !== null) { $this->rawData = json_encode($this->data, JSON_THROW_ON_ERROR) . "\x0a\x00"; } return pack('CCx2IIx2SI', $this->head, $this->version, $this->sessionId, $this->sequence, $this->msgId, strlen($this->rawData)) . $this->rawData; } public function getData() : ?array { return $this->data; } public function getRawData() : ?string { return $this->rawData; } public function getSession() : int { return $this->sessionId; } public function getSequence() : int { return $this->sequence; } public function getMessageType() : string { $types = array_flip(static::MESSAGE_CODES); if (!isset($types[$this->msgId])) { throw new \Exception('Unknown message type: ' . $this->msgId); } return $types[$this->msgId]; } } 

рдФрд░ рдПрдХ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ

 yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.request.login'], [ 'EncryptType' => 'MD5', 'LoginType' => 'DVRIP-Web', 'PassWord' => sofiaHash('admin'), 'UserName' => 'admin', ])); 

рд╣рд╛рдБ, рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ред рд╣рдордиреЗ рдХрдиреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдФрд░ рдПрдХ рд╕рдВрджреЗрд╢ рднреЗрдЬрд╛, рд▓реЗрдХрд┐рди рд╣рдо рдпрд╣ рднреА рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХреИрдорд░рд╛ рд╕рд╣реА рдерд╛ рдФрд░ рдХрдо рд╕реЗ рдХрдо рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рдЙрд╕ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдЧрдИ рдереАред рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рдЙрддреНрддрд░ рдХреЛ рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдЪрд▓реЛ рдЗрд╕реЗ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдХрд░рддреЗ рд╣реИрдВ), рдЗрд╕рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреИрдХреЗрдЯ рдЪреБрдиреЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдбреАрдХреЛрдб рдХрд░реЗрдВред

рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкреИрдХреЗрдЯреЛрдВ рдХреЗ рддрд░реНрдХ рдХреЛ рдХрд┐рд╕реА рддрд░рд╣ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рд╢рд╛рдо рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдФрд░ рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рд╡рд░реНрдЧ рдХреЛ рд╕реНрдХреЗрдЪ рдХрд┐рдпрд╛ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдбрд┐рдХреЛрдб рдХрд┐рдП рдЧрдП рдкреИрдХреЗрдЯ рдХреЛ рдлреЗрдВрдХ рджреЗрдЧрд╛

 class Reader extends EventEmitter { protected InputStream $socket; public function __construct(InputStream $socket) { $this->socket = $socket; } public function start() : \Generator { $buffer = ''; while (!$this->socket->isClosed() && $result = yield Packet::read($this->socket, $buffer)) { [$packet, $chunk] = $result; $buffer = $chunk; $chunk = null; $this->emit('packet', [$packet]); $this->emit($packet->getMessageType(), [$packet]); } $buffer = null; } } 

рдФрд░ рд╣рдорд╛рд░реЗ рдкреИрдХреЗрдЯ рд╡рд░реНрдЧ рдореЗрдВ рдХреБрдЫ рд╕реНрдерд┐рд░ рддрд░реАрдХреЛрдВ рдХреЛ рдЬреЛрдбрд╝рд╛, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░реАрдо рд╕реЗ рдкреИрдХреЗрдЯ рдХреЛ рдирд┐рдХрд╛рд▓реЗрдВрдЧреЗ рдФрд░ рдбрд┐рдХреЛрдб рдХрд░реЗрдВрдЧреЗред

 public static function read(InputStream $socket, string $buffer = '') : Promise { return call(function () use ($socket, $buffer) { $header = null; do { if ($header === null && strlen($buffer) > 20) { $header = unpack('Chead/Cversion/x2/IsessionId/Isequence/x2/SmsgId/Ilen', substr($buffer, 0, 20)); $buffer = substr($buffer, 20); } if ($header !== null && strlen($buffer) >= (int) $header['len']) { return [ static::fromRaw($header, (int) $header['len'] > 0 ? substr($buffer, 0, (int) $header['len']) : null), substr($buffer, (int) $header['len']) ]; } $buffer .= yield $socket->read(); } while (!$socket->isClosed()); }); } protected static function fromRaw(array $header, ?string $rawData) : self { $packet = new static($header['msgId'], null, $header['sequence'], $header['sessionId']); $packet->rawData = $rawData; $packet->data = (int) $packet->msgId === static::MESSAGE_CODES['packet.binary'] || $rawData === null ? null : json_decode(substr($rawData, 0, -2), true, 512, JSON_THROW_ON_ERROR); return $packet; } 

рдЕрдм, рдИрд╡рдирдореЗрдВрдЯ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рд╣рдо рдлреЙрд░реНрдо рдореЗрдВ рдЕрдкрдиреЗ рддрд░реНрдХ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

 $reader->on($packetType, $handler); 

рдФрд░ рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдпрд╣ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдорд┐рд▓реА, рдЬрд╣рд╛рдБ рдореИрдВрдиреЗ рдПрдХ рдФрд░ Keep Alive рдФрд░ SIGINT / SIGTERM рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдЬреЛрдбрд╝рд╛:

 $reader = new Reader($socket = yield connect('tcp://10.0.5.100:49152')); $reader->on('packet.response.login', asyncCoroutine(function (Packet $packet) use ($socket) { if (empty($packet->getData()['Ret']) || !in_array($packet->getData()['Ret'], Packet::SUCCESS_CODES)) { throw new \Exception('Wrong login data'); } yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.request.claim'], [ 'Name' => 'OPMonitor', 'OPMonitor' => ['Action' => 'Claim', 'Parameter' => ['Channel' => 0, 'CombinMode' => 'NONE', 'StreamType' => 'Main', 'TransMode' => 'TCP']], ], 1, $packet->getSession())); })); $reader->once('packet.response.login', function (Packet $packet) use ($socket) { Loop::unreference(Loop::repeat($packet->getData()['AliveInterval'] * 1000, function ($watcherId) use ($socket, $packet) { if ($socket->getResource() === null) { return Loop::cancel($watcherId); } yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.request.keepAlive'], [ 'Name' => 'KeepAlive', 'SessionID' => $packet->getData()['SessionID'] ], 0, $packet->getSession())); })); }); $reader->on('packet.response.claim', asyncCoroutine(function (Packet $packet) use ($socket) { yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.videoControl'], [ 'Name' => 'OPMonitor', 'OPMonitor' => ['Action' => 'Start', 'Parameter' => ['Channel' => 0, 'CombinMode' => 'NONE', 'StreamType' => 'Main', 'TransMode' => 'TCP']], ], $packet->getSequence() + 1, $packet->getSession())); })); $emitter = new Emitter(); $reader->on('packet.binary', function ($packet) use ($emitter) { $emitter->emit($packet->getRawData()); }); $reader->once('packet.binary', function (Packet $packet) use ($socket) { $signalHandler = function () use ($socket, $packet) { yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.videoControl'], [ 'Name' => 'OPMonitor', 'OPMonitor' => ['Action' => 'Stop', 'Parameter' => ['Channel' => 0, 'CombinMode' => 'NONE', 'StreamType' => 'Main', 'TransMode' => 'TCP']], ], 0, $packet->getSession())); $socket->close(); }; Loop::unreference(Loop::onSignal(defined('SIGINT') ? SIGINT : 2, $signalHandler, 'SIGINT')); Loop::unreference(Loop::onSignal(defined('SIGTERM') ? SIGTERM : 15, $signalHandler, 'SIGTERM')); }); asyncCall([$reader, 'start']); yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.request.login'], [ 'EncryptType' => 'MD5', 'LoginType' => 'DVRIP-Web', 'PassWord' => sofiaHash('123qwea'), 'UserName' => 'admin', ])); yield pipe(new IteratorStream($emitter->iterate()), getStdout()); 

рдпрд╣ рдмрд┐рдирд╛ рдХрд╣реЗ рдЪрд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рд╕реНрдЯрдбрдЖрдЙрдЯ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдЬрд╣рд╛рдВ рдЪрд╛рд╣реЗрдВ, рд╡реАрдбрд┐рдпреЛ рд╕реНрдЯреНрд░реАрдо рдХреЛ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЕрдВрддрд┐рдо рд╕реНрдХреНрд░рд┐рдкреНрдЯ
 <?php ini_set('display_errors', 'stderr'); use Amp\Emitter; use Amp\Loop; use Amp\Promise; use Amp\ByteStream\InputStream; use Amp\ByteStream\IteratorStream; use Evenement\EventEmitter; use function Amp\call; use function Amp\asyncCall; use function Amp\asyncCoroutine; use function Amp\ByteStream\getStderr; use function Amp\ByteStream\getStdout; use function Amp\ByteStream\pipe; use function Amp\Socket\connect; require 'vendor/autoload.php'; function sofiaHash(string $password) : string { $md5 = md5($password, true); return implode('', array_map(function ($i) use ($md5) { $c = (ord($md5[2 * $i]) + ord($md5[2 * $i + 1])) % 62; $c += $c > 9 ? ($c > 35 ? 61 : 55) : 48; return chr($c); }, range(0, 7))); } class Reader extends EventEmitter { protected InputStream $socket; public function __construct(InputStream $socket) { $this->socket = $socket; } public function start() : \Generator { $buffer = ''; while (!$this->socket->isClosed() && $result = yield Packet::read($this->socket, $buffer)) { [$packet, $chunk] = $result; $buffer = $chunk; $chunk = null; $this->emit('packet', [$packet]); $this->emit($packet->getMessageType(), [$packet]); } $buffer = null; } } class Packet { public const SUCCESS_CODES = [100, 515]; public const MESSAGE_CODES = [ 'packet.request.login' => 1000, 'packet.request.keepAlive' => 1006, 'packet.request.claim' => 1413, 'packet.response.login' => 1001, 'packet.response.keepAlive' => 1007, 'packet.response.claim' => 1414, 'packet.videoControl' => 1410, 'packet.binary' => 1412, ]; public static function read(InputStream $socket, string $buffer = '') : Promise { return call(function () use ($socket, $buffer) { $header = null; do { if ($header === null && strlen($buffer) > 20) { $header = unpack('Chead/Cversion/x2/IsessionId/Isequence/x2/SmsgId/Ilen', substr($buffer, 0, 20)); $buffer = substr($buffer, 20); } if ($header !== null && strlen($buffer) >= (int) $header['len']) { return [ static::fromRaw($header, (int) $header['len'] > 0 ? substr($buffer, 0, (int) $header['len']) : null), substr($buffer, (int) $header['len']) ]; } $buffer .= yield $socket->read(); } while (!$socket->isClosed()); }); } protected static function fromRaw(array $header, ?string $rawData) : self { $packet = new static($header['msgId'], null, $header['sequence'], $header['sessionId']); $packet->rawData = $rawData; $packet->data = (int) $packet->msgId === static::MESSAGE_CODES['packet.binary'] || $rawData === null ? null : json_decode(substr($rawData, 0, -2), true, 512, JSON_THROW_ON_ERROR); return $packet; } protected int $head = 255; protected int $version = 0; protected int $sessionId; protected int $sequence; protected int $msgId; protected ?string $rawData; protected ?array $data; public function __construct(int $msgId, ?array $data = null, int $sequence = 0, int $sessionId = 0) { $this->msgId = $msgId; $this->data = $data; $this->sequence = $sequence; $this->sessionId = $sessionId; } public function __toString() : string { if ($this->data !== null) { $this->rawData = json_encode($this->data, JSON_THROW_ON_ERROR) . "\x0a\x00"; } return pack('CCx2IIx2SI', $this->head, $this->version, $this->sessionId, $this->sequence, $this->msgId, strlen($this->rawData)) . $this->rawData; } public function getData() : ?array { return $this->data; } public function getRawData() : ?string { return $this->rawData; } public function getSession() : int { return $this->sessionId; } public function getSequence() : int { return $this->sequence; } public function getMessageType() : string { $types = array_flip(static::MESSAGE_CODES); if (!isset($types[$this->msgId])) { throw new \Exception('Unknown message type: ' . $this->msgId); } return $types[$this->msgId]; } } Loop::run(function () : \Generator { $reader = new Reader($socket = yield connect('tcp://10.0.5.100:49152')); $reader->on('packet.response.login', asyncCoroutine(function (Packet $packet) use ($socket) { if (empty($packet->getData()['Ret']) || !in_array($packet->getData()['Ret'], Packet::SUCCESS_CODES)) { throw new \Exception('Wrong login data'); } yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.request.claim'], [ 'Name' => 'OPMonitor', 'OPMonitor' => ['Action' => 'Claim', 'Parameter' => ['Channel' => 0, 'CombinMode' => 'NONE', 'StreamType' => 'Main', 'TransMode' => 'TCP']], ], 1, $packet->getSession())); })); $reader->once('packet.response.login', function (Packet $packet) use ($socket) { Loop::unreference(Loop::repeat($packet->getData()['AliveInterval'] * 1000, function ($watcherId) use ($socket, $packet) { if ($socket->getResource() === null) { return Loop::cancel($watcherId); } yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.request.keepAlive'], [ 'Name' => 'KeepAlive', 'SessionID' => $packet->getData()['SessionID'] ], 0, $packet->getSession())); })); }); $reader->on('packet.response.claim', asyncCoroutine(function (Packet $packet) use ($socket) { yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.videoControl'], [ 'Name' => 'OPMonitor', 'OPMonitor' => ['Action' => 'Start', 'Parameter' => ['Channel' => 0, 'CombinMode' => 'NONE', 'StreamType' => 'Main', 'TransMode' => 'TCP']], ], $packet->getSequence() + 1, $packet->getSession())); })); $emitter = new Emitter(); $reader->on('packet.binary', function ($packet) use ($emitter) { $emitter->emit($packet->getRawData()); }); $reader->once('packet.binary', function (Packet $packet) use ($socket) { $signalHandler = function () use ($socket, $packet) { yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.videoControl'], [ 'Name' => 'OPMonitor', 'OPMonitor' => ['Action' => 'Stop', 'Parameter' => ['Channel' => 0, 'CombinMode' => 'NONE', 'StreamType' => 'Main', 'TransMode' => 'TCP']], ], 0, $packet->getSession())); $socket->close(); }; Loop::unreference(Loop::onSignal(defined('SIGINT') ? SIGINT : 2, $signalHandler, 'SIGINT')); Loop::unreference(Loop::onSignal(defined('SIGTERM') ? SIGTERM : 15, $signalHandler, 'SIGTERM')); }); asyncCall([$reader, 'start']); yield $socket->write((string) new Packet(Packet::MESSAGE_CODES['packet.request.login'], [ 'EncryptType' => 'MD5', 'LoginType' => 'DVRIP-Web', 'PassWord' => sofiaHash('123qwea'), 'UserName' => 'admin', ])); yield pipe(new IteratorStream($emitter->iterate()), getStdout()); }); 

рдЕрдм рд╣рдо рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╡реАрдбрд┐рдпреЛ рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рд░рд┐рдХреЙрд░реНрдб рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

 $ php recorder.php > output.h264 

рд╣рдордиреЗ рдПрдХ SIGINT рд╣реИрдВрдбрд▓рд░ рдЬреЛрдбрд╝рд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЬрдм рдЖрдк рдердХ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдмрд╕ Ctrl + C рджрдмрд╛рдПрдВ рдФрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╡реАрдбрд┐рдпреЛ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХреЛ рд░реЛрдХ рджреЗрдЧрд╛ рдФрд░ рдХрдиреЗрдХреНрд╢рди рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛ред

рдФрд░ рд╣рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, ffmpeg рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░реАрдо рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░реЗрдВ рдФрд░ рдордХреНрдЦреА рдкрд░ рдЯреНрд░рд╛рдВрд╕рдХреЛрдб рдХрд░реЗрдВред

 $ php recorder.php | ffmpeg -nostdin -y -hide_banner -loglevel verbose -f h264 -i pipe:0 -pix_fmt yuv420p -c copy -movflags +frag_keyframe+empty_moov+default_base_moof -reset_timestamps 1 -f mpegts output.mpegts 

рдФрд░ рдЖрдк рдлрд╛рд░реНрдо рдХреА рдЙрдиреНрдорддреНрдд рд╢реНрд░реГрдВрдЦрд▓рд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ

 $ php recorder.php | ffmpeg ... | curl -d @- ... 

рдХрд┐рд╕реА рднреА рддрд░рд╣ рдХреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╕рд╛рде рдпрд╣ рд╕рдм рд╢реБрд░реВ рдХрд░рдирд╛ рдЬреЛ рд╣рд░ рдШрдВрдЯреЗ рд╢реБрд░реВ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ 1 рдШрдВрдЯреЗ рддрдХ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдЪрд┐рдХрдиреЗ рдЯреБрдХрдбрд╝реЗ рдорд┐рд▓реЗрдВрдЧреЗ, рдЬрд╣рд╛рдВ рднреА рд╣рдореЗрдВ рдЬрд░реВрд░рдд рд╣реЛрдЧреАред

рдХреНрдпреЛрдВ?


рдореБрдЭреЗ рд╡рд┐рд╢реНрд╡рд╛рд╕ рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ "рдХреНрдпреЛрдВ?" рдХреИрдорд░реЛрдВ рд╕реЗ рдкрдВрдЬреАрдХрд░рдг рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╕рдорд╛рдзрд╛рди рд╣реИрдВ, рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдХреИрдорд░реЗ рдЦреБрдж рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдиреНрд╣реЛрдВрдиреЗ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕рд╣реА рдЖрдкрддреНрддрд┐ рдХреА рдереА, рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░ рдЗрд╕реЗ рдмрд╣реБрдд рдЖрд╕рд╛рди рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рдерд╛ред

рдпрд╣ рд╕рд┐рд░реНрдл рдЗрддрдирд╛ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдЦрд╛рд▓реА рд╕рдордп рдерд╛ рдЬреЛ рдореБрдЭреЗ рдХрд╣реАрдВ рдФрд░ рдХрд░рдирд╛ рдерд╛, рдЕрдкрдиреА рддрд░рд╣ рд╕реЗ рдмрдирд╛рдиреЗ рдХреА рдЗрдЪреНрдЫрд╛ рдФрд░ рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдкрд░рд┐рд╣рд╛рд░реНрдп рд▓рд╛рд▓рд╕рд╛ред

рдФрд░ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдмреЗрд╢рдХ, рд▓реЗрдЦ рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдХреБрдЫ рд╕рдВрд╢реЛрдзрдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЖрдкрдХреЛ рдЗрд╕реЗ рдЗрд╕ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП - рдореИрдВ рджреЛрд╣рд░рд╛рддрд╛ рд╣реВрдВ, рдпрд╣ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рдкреНрд░рдорд╛рдг рд╣реИред рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдореИрдВ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдШрд░ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдШреБрдЯрдиреЗ рд╕реЗ рдКрдВрдЪреЗ рдШрд░ рд╕реЗ рдмрдиреЗ рдЙрддреНрдкрд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХрдбрд╝реА рдЪреЗрддрд╛рд╡рдиреА рджреЗрддрд╛ рд╣реВрдВред
рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╡рд┐рд╢реНрд╡рд╕рдиреАрдпрддрд╛ рдЗрддрдиреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╡рд┐рдХрд▓реНрдк рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░ рдирдЬрд░ рд░рдЦрдиреЗ рд╡рд╛рд▓рд╛ рдЗрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдкрд░ рдХрддрд╛рдИ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЬреЛ рдзрд╛рд░рд╛ рдХреЛ ffmpeg рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдШрдВрдЯреЗ рджреНрд╡рд╛рд░рд╛ рдЯреБрдХрдбрд╝реЛрдВ рдХреЛ рд░рд┐рдХреЙрд░реНрдб рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡реАрдХреЗ рдкрд░ рдЕрдкрд▓реЛрдб рдХрд░рддрд╛ рд╣реИ, рдПрдХ рдбрд┐рд╕реНрдХрдиреЗрдХреНрд╢рди рдпрд╛ рдХреБрдЫ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рдШрдЯрдирд╛рдУрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рддрд╛ рд╣реИред

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпрд╣ рд╕рдм рдЯреАрд╕реАрдПрд╕ рдкрд░ рдЖрд░рдЯреАрдПрд╕рдкреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡реАрдбрд┐рдпреЛ рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рдиреЗ рд╕реЗ рдмрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рдерд╛, рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди ffmpeg рдиреЗ рд╕рдордп рдкрд░ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдХреНрд╖рдг рдореЗрдВ рдореВрд░реНрдЦрддрд╛рдкреВрд░реНрдг рд╕реНрдЯрд╛рд▓ рдХреЛ рдкрд╕рдВрдж рдХрд┐рдпрд╛ рдФрд░ рдХреЗрд╡рд▓ SIGKILL рдХреЛ рдЬрд╡рд╛рдм рджреЗрдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред

рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реЛрдиреЗ рд▓рдЧрд╛ рдХрд┐ рдпрд╣ рд╕рдм рдЗрд╕рд▓рд┐рдП рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдкреИрд░реЗрдВрдЯ рд╕реНрдХреНрд░рд┐рдкреНрдЯ-рд╡реЙрдЪ рдХреЛ рдореБрдХреБрдЯ рджреНрд╡рд╛рд░рд╛ рдЪрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдЙрд╕реЗ рдХрдо рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдорд┐рд▓реА рдереА, рд▓реЗрдХрд┐рди рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдмрдврд╝рдиреЗ рд╕реЗ рд╕рдорд╕реНрдпрд╛ рдХреА рдЖрд╡реГрддреНрддрд┐ рдХрдо рд╣реЛ рдЧрдИред

рдЙрдкрд░реЛрдХреНрдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕реНрдерд┐рд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЕрднреА рддрдХ рдХрд┐рд╕реА рднреА рд╢рд┐рдХрд╛рдпрдд рдХреЛ рдирд╣реАрдВ рдЙрдард╛рдпрд╛ рд╣реИред

Source: https://habr.com/ru/post/hi484518/


All Articles