ÀÖÓãµç¾º

    1. ½ÌÓýÐÐÒµA¹ÉIPOµÚÒ»¹É£¨¹ÉƱ´úÂë 003032£©

      È«¹ú×Éѯ/ͶËßÈÈÏߣº400-618-4000

      JavaÈçºÎʵÏÖÔÚÏß²¥·Å¹¦ÄÜ£¿

      ¸üÐÂʱ¼ä:2020Äê10ÔÂ28ÈÕ14ʱ18·Ö À´Ô´:ÀÖÓã²¥¿Í ä¯ÀÀ´ÎÊý:

      1. ÊÓÆµµã²¥ÐèÇó·ÖÎö

      1.1 ÐèÇóÃèÊö

      ÊÓÆµµã²¥ÐèÇóÈçÏ£º

      1¡¢Ñ§Éú¿ÉÒÔÔÚwindowsä¯ÀÀÆ÷ÉÏÔÚÏß¹Û¿´ÊÓÆµ¡£

      2¡¢²¥·ÅÆ÷¾ßÓÐ¿ì½ø¡¢¿ìÍË¡¢ÔÝÍ£µÈ»ù±¾¹¦ÄÜ¡£

      1.2 ÊÓÆµµã²¥½â¾ö·½°¸

      1.2.1 Á÷ýÌå

      Á÷ýÌå

      Ïêϸ²Î¿¼£ºhttps://baike.baidu.com/item/%E6%B5%81%E5%AA%92%E4%BD%93/98740?fr=aladdin

      ¸ÅÀ¨Àí½â£ºÁ÷ýÌå¾ÍÊǽ«ÊÓÆµÎļþ·Ö³ÉÐí¶àС¿é¶ù£¬½«ÕâЩС¿é¶ù×÷ΪÊý¾Ý°üͨ¹ýÍøÂç·¢ËͳöÈ¥£¬ÊµÏÖÒ»±ß´«ÊäÊÓÆµ Êý¾Ý °üÒ»±ß¹Û¿´ÊÓÆµ¡£

      Á÷ʽ´«Êä

      ÔÚÍøÂçÉÏ´«ÊäÒô¡¢ÊÓÆµÐÅÏ¢ÓÐÁ½¸ö·½Ê½£ºÏÂÔØºÍÁ÷ʽ´«Êä¡£

      ÏÂÔØ£º¾ÍÊǰÑÒô¡¢ÊÓÆµÎļþÍêÈ«ÏÂÔØµ½±¾»úºó¿ªÊ¼²¥·Å£¬ËüµÄÌØµãÊDZØÐëµÈµ½ÊÓÆµÎļþÏÂÔØÍê³É·½¿É²¥·Å£¬²¥·ÅµÈ´ýʱ¼ä½Ï³¤£¬ÎÞ·¨È¥²¥·Å»¹Î´ÏÂÔØµÄ²¿·ÖÊÓÆµ¡£

      Á÷ʽ´«Ê䣺¾ÍÊǿͻ§¶Ëͨ¹ýÁ´½ÓÊÓÆµ·þÎñÆ÷ʵʱ´«ÊäÒô¡¢ÊÓÆµÐÅÏ¢£¬ÊµÏÖ“±ßÏÂÔØ±ß²¥·Å”¡£

      Á÷ʽ´«Êä°üÀ¨ÈçÏÂÁ½ÖÖ·½Ê½£º

      1) ˳ÐòÁ÷ʽ´«Êä

      ¼´Ë³ÐòÏÂÔØÒô¡¢ÊÓÆµÎļþ£¬¿ÉÒÔʵÏÖ±ßÏÂÔØ±ß²¥·Å£¬²»¹ý£¬Óû§Ö»Äܹۿ´ÒÑÏÂÔØµÄÊÓÆµÄÚÈÝ£¬ÎÞ·¨¿ì½øµ½Î´ÏÂÔØµÄÊÓÆµ²¿·Ö£¬Ë³ÐòÁ÷ʽ´«Êä¿ÉÒÔʹÓÃHttp·þÎñÆ÷À´ÊµÏÖ£¬±ÈÈçNginx¡¢ApacheµÈ¡£

      2)ʵʱÁ÷ʽ´«Êä

      ʵʱÁ÷ʽ´«Êä¿ÉÒÔ½â¾ö˳ÐòÁ÷ʽ´«ÊäÎÞ·¨¿ì½øµÄÎÊÌ⣬ËüÓëHttpÁ÷ʽ´«Ê䲻ͬ£¬Ëü±ØÐëʹÓÃÁ÷ýÌå·þÎñÆ÷²¢ÇÒʹÓÃÁ÷ýÌåЭÒéÀ´´«ÊäÊÓÆµ£¬Ëü±ÈHttpÁ÷ʽ´«Ê临ÔÓ¡£³£¼ûµÄʵʱÁ÷ʽ´«ÊäЭÒéÓÐRTSP¡¢RTMP¡¢RSVPµÈ¡£

      Á÷ýÌåϵͳµÄ¸ÅÒª½á¹¹

      ͨ¹ýÁ÷ýÌåϵͳµÄ¸ÅÒª½á¹¹Ñ§Ï°Á÷ýÌåϵͳµÄ»ù±¾ÒµÎñÁ÷³Ì¡£

      1¡¢½«Ô­Ê¼µÄÊÓÆµÎļþͨ¹ý±àÂëÆ÷ת»»ÎªÊʺÏÍøÂç´«ÊäµÄÁ÷¸ñʽ£¬±àÂëºóµÄÊÓÆµÖ±½ÓÊäË͸øÃ½Ìå·þÎñÆ÷¡£

      ԭʼµÄÊÓÆµÎļþͨ³£ÊÇÊÂÏÈÂ¼ÖÆºÃµÄÊÓÆµ£¬±ÈÈçͨ¹ýÉãÏñ»ú¡¢ÉãÏñÍ·µÈ¼Ïñ¡¢Â¼ÒôÉ豸²É¼¯µ½µÄÒôÊÓÆµÎļþ£¬Ìå»ý½Ï´ó£¬ÒªÏëÔÚÍøÂçÉÏ´«ÊäÐèÒª¾­¹ýѹËõ´¦Àí£¬¼´Í¨¹ý±àÂëÆ÷½øÐбàÂë ¡£

      2¡¢Ã½Ìå·þÎñ»ñÈ¡µ½±àÂëºÃµÄÊÓÆµÎļþ£¬¶ÔÍâÌṩÁ÷ýÌåÊý¾Ý´«Êä½Ó¿Ú£¬½Ó¿ÚЭÒé°üÀ¨ £ºHTTP¡¢RTSP¡¢RTMPµÈ

      3¡¢²¥·ÅÆ÷ͨ¹ýÁ÷ýÌåЭÒéÓëýÌå·þÎñÆ÷ͨÐÅ£¬»ñÈ¡ÊÓÆµÊý¾Ý£¬²¥·ÅÊÓÆµ¡£

      1.2.2 µã²¥·½°¸

      ±¾ÏîÄ¿°üÀ¨µã²¥ºÍÖ±²¥Á½ÖÖ·½Ê½£¬ÎÒÃÇÏȵ÷Ñе㲥µÄ·½°¸£¬ÈçÏ£º

      1¡¢ ²¥·ÅÆ÷ͨ¹ý httpЭÒé´Óhttp·þÎñÆ÷ÉÏÏÂÔØÊÓÆµÎļþ½øÐв¥·Å

      ÎÊÌ⣺±ØÐëµÈµ½ÊÓÆµÏÂÔØÍê²Å¿ÉÒÔ²¥·Å£¬²»Ö§³Ö¿ì½øµ½Ä³¸öʱ¼äµã½øÐв¥·Å

      2¡¢ ²¥·ÅÆ÷ͨ¹ýrtmpЭÒéÁ¬½ÓýÌå·þÎñÆ÷ÒÔʵʱÁ÷·½Ê½²¥·ÅÊÓÆµ

      ʹÓÃrtmpЭÒéÐèÒª¼ÜÉèýÌå·þÎñÆ÷£¬Ôì¼Û¸ß£¬¶ÔÓÚÖ±²¥¶à²ÉÓô˷½°¸¡£

      3¡¢ ²¥·ÅÆ÷ʹÓÃHLSЭÒéÁ¬½Óhttp·þÎñÆ÷(Nginx¡¢ApacheµÈ)ʵÏÖ½üʵʱÁ÷·½Ê½²¥·ÅÊÓÆµ

      HLSЭÒ鹿¶¨£º»ùÓÚHttpЭÒ飬ÊÓÆµ·â×°¸ñʽΪts£¬ÊÓÆµµÄ±àÂë¸ñʽΪH264,ÒôƵ±àÂë¸ñʽΪMP3¡¢AAC»òÕßAC-3

      HLSÊÇʲô ?

      HLS

      HLSµÄ¹¤×÷·½Ê½ÊÇ£º½«ÊÓÆµ²ð·Ö³ÉÈô¸Éts¸ñʽµÄСÎļþ£¬Í¨¹ým3u8¸ñʽµÄË÷ÒýÎļþ¶ÔÕâЩtsСÎļþ½¨Á¢Ë÷Òý¡£Ò»°ã10ÃëÒ»¸ötsÎļþ£¬²¥·ÅÆ÷Á¬½Óm3u8Îļþ²¥·Å£¬µ±¿ì½øÊ±Í¨¹ým3u8¼´¿ÉÕÒµ½¶ÔÓ¦µÄË÷ÒýÎļþ£¬²¢È¥ÏÂÔØ¶ÔÓ¦µÄtsÎļþ£¬´Ó¶øÊµÏÖ¿ì½ø¡¢¿ìÍËÒÔ½üʵʱ µÄ·½Ê½²¥·ÅÊÓÆµ¡£

      IOS¡¢AndroidÉ豸¡¢¼°¸÷´óä¯ÀÀÆ÷¶¼Ö§³ÖHLSЭÒé¡£

      ýÌå·þÎñÆ÷

      Ïêϸ²Î¿¼£ºhttps://baike.baidu.com/item/HLS/8328931?fr=aladdin

      ²ÉÓÃHLS·½°¸¼´¿ÉʵÏÖ±ßÏÂÔØ±ß²¥·Å£¬¿ÉÒÔ²»ÓÃʹÓÃrtmpµÈÁ÷ýÌåЭÒ飬²»Óù¹½¨×¨ÓõÄýÌå·þÎñÆ÷£¬½ÚÊ¡³É±¾¡£

      ±¾ÏîÄ¿µã²¥·½°¸È·¶¨Îª·½°¸3¡£

      2 FFmpeg µÄ»ù±¾Ê¹ÓÃ

      ÎÒÃǽ«ÊÓÆµÂ¼ÖÆÍê³Éºó£¬Ê¹ÓÃÊÓÆµ±àÂëÈí¼þ¶ÔÊÓÆµ½øÐбàÂ룬±¾ÏîÄ¿ ʹÓÃFFmpeg¶ÔÊÓÆµ½øÐбàÂë ¡£

      ffmpeg

      ÏÂÔØ £ºffmpeg-20180227-fa0c9d6-win64-static.zip£¬²¢½âѹ£¬±¾½Ì³Ì½«ffmpeg½âѹµ½ÁËC:\Java_Soft\xczx\ffmpeg-20180227-fa0c9d6-win64-staticÏ¡£

      FFmpeg±»Ðí¶à¿ªÔ´ÏîÄ¿²ÉÓã¬QQÓ°Òô¡¢±©·çÓ°Òô¡¢VLCµÈ¡£

      ÏÂÔØ£ºFFmpeg https://www.ffmpeg.org/download.html#build-windows

      ½«C:\Java_Soft\xczx\ffmpeg-20180227-fa0c9d6-win64-static\binĿ¼ÅäÖÃÔÚpath»·¾³±äÁ¿ÖС£

      ¼ì²âÊÇ·ñ°²×°³É¹¦


      ¼òµ¥µÄ²âÊÔ£º

      ½«Ò»¸ö.aviÎļþת³Émp4¡¢mp3¡¢gifµÈ¡£

      ±ÈÈçÎÒÃǽ«lucene.aviÎļþת³Émp4£¬ÔËÐÐÈçÏÂÃüÁ

      ffmpeg -i lucene.avi lucene.mp4

      ת³Émp3£ºffmpeg -i lucene.avi lucene.mp3

      ת³Égif£ºffmpeg -i lucene.avi lucene.gif

      ¹Ù·½Îĵµ(Ó¢ÎÄ)£ºhttp://ffmpeg.org/ffmpeg.html

      2.1 Éú³Ém3u8/tsÎļþ

      ʹÓÃffmpegÉú³É m3u8µÄ²½ÖèÈçÏ£º

      µÚÒ»²½£ºÏȽ«aviÊÓÆµ×ª³Émp4


      ffmpeg.exe -i  lucene.avi -c:v libx264 -s 1280x720 -pix_fmt yuv420p -b:a 63k -b:v 753k -r 18 .\lucene.mp4

      ÏÂÃæ°Ñ¸÷²ÎÊýÒâ˼´ó¸Å½²½²£¬´ó¸ÅÁ˽âÒâ˼¼´¿É£¬²»ÔÙ´ËÕ¹¿ªÁ÷ýÌåרҵ֪ʶµÄ½²½â¡£

      -c:v ÊÓÆµ±àÂëΪx264 £¬x264±àÂëÊÇH264µÄÒ»ÖÖ¿ªÔ´±àÂë¸ñʽ¡£

      -s ÉèÖ÷ֱæÂÊ

      -pix_fmt yuv420p£ºÉèÖÃÏñËØ²ÉÑù·½Ê½£¬Ö÷Á÷µÄ²ÉÑù·½Ê½ÓÐÈýÖÖ£¬YUV4:4:4£¬YUV4:2:2£¬YUV4:2:0£¬ËüµÄ×÷ÓÃÊǸù¾Ý²ÉÑù·½Ê½À´´ÓÂëÁ÷Öл¹Ô­Ã¿¸öÏñËØµãµÄYUV(ÁÁ¶ÈÐÅÏ¢ÓëÉ«²ÊÐÅÏ¢)Öµ¡£

      -b ÉèÖÃÂëÂÊ£¬-b:aºÍ-b:v·Ö±ð±íʾÒôƵµÄÂëÂʺÍÊÓÆµµÄÂëÂÊ£¬-b±íʾÒôƵ¼ÓÊÓÆµµÄ×ÜÂëÂÊ¡£ÂëÂʶÔÒ»¸öÊÓÆµÖÊÁ¿ÓкܴóµÄ×÷Óá£

      -r£ºÖ¡ÂÊ£¬±íʾÿÃë¸üÐÂͼÏñ»­ÃæµÄ´ÎÊý£¬Í¨³£´óÓÚ24ÈâÑÛ¾ÍûÓÐÁ¬¹áÓëÍ£¶ÙµÄ¸Ð¾õÁË¡£

      µÚ¶þ²½£º½«mp4Éú³Ém3u8


      ffmpeg -i  lucene.mp4   -hls_time 10 -hls_list_size 0  -hls_segment_filename ./hls/lucene_%05d.ts ./hls/lucene.m3u8

      -hls_time ÉèÖÃÿƬµÄ³¤¶È£¬µ¥Î»ÎªÃë

      -hls_list_size n: ±£´æµÄ·ÖƬµÄÊýÁ¿£¬ÉèÖÃΪ0±íʾ±£´æËùÓÐ·ÖÆ¬

      -hls_segment_filename £º¶ÎÎļþµÄÃû³Æ£¬%05d±íʾ5λÊý×Ö

      Éú³ÉµÄЧ¹ûÊÇ£º½«lucene.mp4ÊÓÆµÎļþÿ10ÃëÉú³ÉÒ»¸ötsÎļþ£¬×îºóÉú³ÉÒ»¸öm3u8Îļþ£¬m3u8ÎļþÊÇtsµÄË÷ÒýÎļþ¡£

      ʹÓÃVLC´ò¿ªm3u8Îļþ£¬²âÊÔ²¥·ÅЧ¹û£¬VLC ÊÇÒ»¿î×ÔÓÉ¡¢¿ªÔ´µÄ¿çƽ̨¶àýÌå²¥·ÅÆ÷¼°¿ò¼Ü£¬¿É²¥·Å´ó¶àÊý¶àýÌåÎļþ£¬ÒÔ¼° DVD¡¢ÒôƵ CD¡¢VCD ¼°¸÷ÀàÁ÷ýÌåЭÒé¡£(http://www.videolan.org/)

      3. ÊÓÆµ(ý×Ê)´¦Àí

      ¿ª·¢»·¾³

      1. ´´½¨Ã½×ÊÊý¾Ý¿â

      µ¼Èëshcool.sql

      ´´½¨Ã½×ÊÊý¾Ý¿â

      2. ´´½¨Ã½×Ê·þÎñ¹¤³Ì

      »ùÓÚspringboot´´½¨¹¤³Ì

      ´´½¨ÃÃ×Ó·þÎñ¹¤³Ì


      3. ÉÏ´«Îļþ

      3.1 ¶ÏµãÐø´«½â¾ö·½°¸

      ͨ³£ÊÓÆµÎļþ¶¼±È½Ï´ó£¬ËùÒÔ¶ÔÓÚý×ÊϵͳÉÏ´«ÎļþµÄÐèÇóÒªÂú×ã´óÎļþµÄÉÏ´«ÒªÇó¡£httpЭÒé±¾Éí¶ÔÉÏ´«Îļþ´óСûÓÐÏÞÖÆ£¬µ«Êǿͻ§µÄÍøÂç»·¾³ÖÊÁ¿¡¢µçÄÔÓ²¼þ»·¾³µÈ²Î²î²»Æë£¬Èç¹ûÒ»¸ö´óÎļþ¿ìÉÏ´«ÍêÁËÍø¶ÏÁË£¬µç¶ÏÁËûÓÐÉÏ´«Íê³É£¬ÐèÒª¿Í»§ÖØÐÂÉÏ´«£¬ÕâÊÇÖÂÃüµÄ£¬ËùÒÔ¶ÔÓÚ´óÎļþÉÏ´«µÄÒªÇó×î»ù±¾µÄÊǶϵãÐø´«¡£

      ʲôÊǶϵãÐø´«£º

      ÒýÓðٶȰٿƣº¶ÏµãÐø´«Ö¸µÄÊÇÔÚÏÂÔØ»òÉÏ´«Ê±£¬½«ÏÂÔØ»òÉÏ´«ÈÎÎñ(Ò»¸öÎļþ»òÒ»¸öѹËõ°ü)ÈËΪµÄ»®·ÖΪ¼¸¸ö²¿·Ö£¬Ã¿Ò»¸ö²¿·Ö²ÉÓÃÒ»¸öÏ߳̽øÐÐÉÏ´«»òÏÂÔØ£¬Èç¹ûÅöµ½ÍøÂç¹ÊÕÏ£¬¿ÉÒÔ´ÓÒѾ­ÉÏ´«»òÏÂÔØµÄ²¿·Ö¿ªÊ¼¼ÌÐøÉÏ´«ÏÂÔØÎ´Íê³ÉµÄ²¿·Ö£¬¶øÃ»ÓбØÒª´ÓÍ·¿ªÊ¼ÉÏ´«ÏÂÔØ£¬¶ÏµãÐø´«¿ÉÒÔÌá¸ß½ÚÊ¡²Ù×÷ʱ¼ä£¬Ìá¸ßÓû§ÌåÑéÐÔ¡£

      ¶ÏµãÐø´«

      ÉÏ´«Á÷³ÌÈçÏ£º

      1¡¢ÉÏ´«Ç°ÏȰÑÎļþ·Ö³É¿é

      2¡¢Ò»¿éÒ»¿éµÄÉÏ´«£¬ÉÏ´«ÖжϺóÖØÐÂÉÏ´«£¬ÒÑÉÏ´«µÄ·Ö¿éÔò²»ÓÃÔÙÉÏ´«

      3¡¢¸÷·Ö¿éÉÏ´«Íê³É×îºóºÏ²¢Îļþ

      ÎļþÏÂÔØÔòͬÀí¡£

      3.2 Îļþ·Ö¿éÓëºÏ²¢

      ΪÁ˸üºÃµÄÀí½âÎļþ·Ö¿éÉÏ´«µÄÔ­Àí£¬Ï±ßÓÃjava´úÂë²âÊÔÎļþµÄ·Ö¿éÓëºÏ²¢¡£

      3.3 Îļþ·Ö¿é

      Îļþ·Ö¿éµÄÁ÷³ÌÈçÏ£º

      1¡¢»ñȡԴÎļþ³¤¶È

      2¡¢¸ù¾ÝÉ趨µÄ·Ö¿éÎļþµÄ´óС¼ÆËã³ö¿éÊý

      3¡¢´ÓÔ´Îļþ¶ÁÊý¾ÝÒÀ´ÎÏòÿһ¸ö¿éÎļþдÊý¾Ý



      //²âÊÔÎļþ·Ö¿é·½·¨
      @Test
      public void testChunk() throws IOException {
          File sourceFile = new File("F:/develop/ffmpeg/lucene.mp4");
      //        File sourceFile = new File("d:/logo.png");
          String chunkPath = "F:/develop/ffmpeg/chunk/";
          File chunkFolder = new File(chunkPath);
          if(!chunkFolder.exists()){
              chunkFolder.mkdirs();
          }
          //·Ö¿é´óС
          long chunkSize = 1024*1024*1;
          //·Ö¿éÊýÁ¿
          long chunkNum = (longMath.ceil(sourceFile.length() * 1.0 / chunkSize );
          if(chunkNum<=0){
              chunkNum = 1;
          }
          //»º³åÇø´óС
          byte[] b = new byte[1024];
          //ʹÓÃRandomAccessFile·ÃÎÊÎļþ
          RandomAccessFile raf_read = new RandomAccessFile(sourceFile, "r");
          //·Ö¿é
          for(int i=0;i
              //´´½¨·Ö¿éÎļþ
              File file = new File(chunkPath+i);
              boolean newFile = file.createNewFile();
              if(newFile){
                  //Ïò·Ö¿éÎļþÖÐдÊý¾Ý
                  RandomAccessFile raf_write = new RandomAccessFile(file, "rw");
                  int len = -1;
                  while((len = raf_read.read(b))!=-1){
                      raf_write.write(b,0,len);
                      if(file.length()>chunkSize){
                          break;
                      }
                  }
                  raf_write.close();
              }

          }
          raf_read.close();

      }


      3.4 ÎļþºÏ²¢

      ÎļþºÏ²¢Á÷³Ì£º

      1¡¢ÕÒµ½ÒªºÏ²¢µÄÎļþ²¢°´ÎļþºÏ²¢µÄÏȺó½øÐÐÅÅÐò

      2¡¢´´½¨ºÏ²¢Îļþ

      3¡¢ÒÀ´Î´ÓºÏ²¢µÄÎļþÖжÁÈ¡Êý¾ÝÏòºÏ²¢ÎļþдÈëÊý¾Ý



      //²âÊÔÎļþºÏ²¢·½·¨
      @Test
      public void testMerge() throws IOException {
          //¿éÎļþĿ¼
          File chunkFolder = new File("F:/develop/ffmpeg/chunk/");
          //ºÏ²¢Îļþ
          File mergeFile = new File("F:/develop/ffmpeg/lucene1.mp4");
          if(mergeFile.exists()){
              mergeFile.delete();
          }
          //´´½¨Ðµĺϲ¢Îļþ
          mergeFile.createNewFile();
          //ÓÃÓÚдÎļþ
          RandomAccessFile raf_write = new RandomAccessFile(mergeFile, "rw");
          //Ö¸ÕëÖ¸ÏòÎļþ¶¥¶Ë
          raf_write.seek(0);
          //»º³åÇø
          byte[] b = new byte[1024];
          //·Ö¿éÁбí
          File[] fileArray = chunkFolder.listFiles();
          // ×ª³É¼¯ºÏ£¬±ãÓÚÅÅÐò
          List<FilefileList = new ArrayList<File>(Arrays.asList(fileArray));
          // ´ÓСµ½´óÅÅÐò
          Collections.sort(fileList, new Comparator<File>() {
              @Override
              public int compare(File o1File o2) {
                  if (Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())) {
                      return -1;
                  }
                  return 1;
              }
          });
          //ºÏ²¢Îļþ
          for(File chunkFile:fileList){
              RandomAccessFile raf_read = new RandomAccessFile(chunkFile,"rw");
              int len = -1;
              while((len=raf_read.read(b))!=-1){
                  raf_write.write(b,0,len);

              }
              raf_read.close();
          }
          raf_write.close();

      }


      4. ǰ¶ËÒ³Ãæ

      WebUploader½éÉÜ

      ÈçºÎÔÚwebÒ³ÃæÊµÏֶϵãÐø´«?

      ³£¼ûµÄ·½°¸ÓУº

      1¡¢Í¨¹ýFlashÉÏ´«£¬±ÈÈçSWFupload¡¢Uploadify¡£

      2¡¢°²×°ä¯ÀÀÆ÷²å¼þ£¬±äÏàµÄpc¿Í»§¶Ë£¬ÓõıȽÏÉÙ¡£

      3¡¢Html5

      Ëæ×Åhtml5µÄÁ÷ÐУ¬±¾ÏîÄ¿²ÉÓÃHtml5Íê³ÉÎļþ·Ö¿éÉÏ´«¡£

      ±¾ÏîĿʹÓÃWebUploaderÍê³É´óÎļþÉÏ´«¹¦ÄܵĿª·¢£¬WebUploader¹ÙÍøµØÖ·£ºhttp://fexteam.gz01.bdysite.com/webuploader/

      web uploader

      ʹÓÃWebUploaderÉÏ´«Á÷³ÌÈçÏ£º

      WebUploaderÉÏ´«Á÷³Ì

      ¹³×Ó·½·¨

      ÔÚwebuploaderÖÐÌṩºÜ¶à¹³×Ó·½·¨£¬Ï±ßÁгöÒ»Ð©ÖØÒªµÄ£º

      ¹³×Ó·½·¨

      ±¾ÏîĿʹÓÃÈçϹ³×Ó·½·¨£º

      1)before-send-file

      ÔÚ¿ªÊ¼¶ÔÎļþ·Ö¿é¶ù֮ǰµ÷Ó㬿ÉÒÔ×öһЩÉÏ´«ÎļþǰµÄ×¼±¸¹¤×÷£¬±ÈÈç¼ì²éÎļþĿ¼ÊÇ·ñ´´½¨Íê³ÉµÈ¡£

      2)before-send

      ÔÚÉÏ´«Îļþ·Ö¿é֮ǰµ÷Óô˷½·¨£¬¿ÉÒÔÇëÇó·þÎñ¶Ë¼ì²é·Ö¿éÊÇ·ñ´æÔÚ£¬Èç¹ûÒÑ´æÔÚÔò´Ë·Ö¿é¶ù²»ÔÙÉÏ´«¡£

      3)after-send-file

      ÔÚËùÓзֿéÉÏ´«Íê³Éºó´¥·¢£¬¿ÉÒÔÇëÇó·þÎñ¶ËºÏ²¢·Ö¿éÎļþ¡£

      ×¢²á¹³×Ó·½·¨Ô´´úÂ룺



      WebUploader.Uploader.register({
        "before-send-file":"beforeSendFile",
        "before-send":"beforeSend",
        "after-send-file":"afterSendFile"
      }


      ¹¹½¨WebUploader

      ʹÓÃwebUploaderǰÐèÒª´´½¨webUploader¶ÔÏó¡£

      Ö¸¶¨ÉÏ´«·Ö¿éµÄµØÖ·£º/api/media/upload/uploadchunk



      // ´´½¨uploader¶ÔÏó£¬ÅäÖòÎÊý
      this.uploader = WebUploader.create(
        {
          swf:"/static/plugins/webuploader/dist/Uploader.swf",//ÉÏ´«ÎļþµÄflashÎļþ£¬ä¯ÀÀÆ÷²»Ö§³Öh5ʱÆô¶¯flash
          server:"/api/media/upload/uploadchunk",//ÉÏ´«·Ö¿éµÄ·þÎñ¶ËµØÖ·£¬×¢Òâ¿çÓòÎÊÌâ
          fileVal:"file",//ÎļþÉÏ´«ÓòµÄname
          pick:"#picker",//Ö¸¶¨Ñ¡ÔñÎļþµÄ°´Å¥ÈÝÆ÷
          auto:false,//ÊÖ¶¯´¥·¢ÉÏ´«
          disableGlobalDnd:true,//½ûµôÕû¸öÒ³ÃæµÄÍÏ×§¹¦ÄÜ
          chunked:true,// ÊÇ·ñ·Ö¿éÉÏ´«
          chunkSize:1*1024*1024// ·Ö¿é´óС£¨Ä¬ÈÏ5M£©
          threads:3// ¿ªÆô¶à¸öỊ̈߳¨Ä¬ÈÏ3¸ö£©
          prepareNextFile:true// ÔÊÐíÔÚÎļþ´«ÊäʱÌáǰ°ÑÏÂÒ»¸öÎļþ×¼±¸ºÃ
        }
      )


      before-send-file

      Îļþ¿ªÊ¼ÉÏ´«Ç°Ç°¶ËÇëÇó·þÎñ¶Ë×¼±¸ÉÏ´«¹¤×÷¡£



      type:"POST",
      url:"/api/media/upload/register",
      data:{
        // ÎļþΨһ±íʾ
        fileMd5:this.fileMd5,
        fileName: file.name,
        fileSize:file.size,
        mimetype:file.type,
        fileExt:file.ext
      }


      before-send

      ÉÏ´«·Ö¿éǰǰ¶ËÇëÇó·þÎñ¶ËУÑé·Ö¿éÊÇ·ñ´æÔÚ¡£



      type:"POST",
      url:"/api/media/upload/checkchunk",
      data:{
        // ÎļþΨһ±íʾ
        fileMd5:this.fileMd5,
        // µ±Ç°·Ö¿éϱê
        chunk:block.chunk,
        // µ±Ç°·Ö¿é´óС
        chunkSize:block.end-block.start
      }


      after-send-file

      ÔÚËùÓзֿéÉÏ´«Íê³Éºó´¥·¢£¬¿ÉÒÔÇëÇó·þÎñ¶ËºÏ²¢·Ö¿éÎļþ¡£



      type:"POST",
      url:"/api/media/upload/mergechunks",
      data:{
        fileMd5:this.fileMd5,
        fileName: file.name,
        fileSize:file.size,
        mimetype:file.type,
        fileExt:file.ext
      }


      Ò³ÃæÐ§¹û

      Ò³ÃæÐ§¹û

      ѧԱʹÓãº

      Ö±½Ó½âѹ×ÊÁÏxc-ui-pc-teachµ½webstorm¹¤×÷Ŀ¼

      ͨ¹ýnginx·ÃÎÊ,ÔÚnginxÖÐÅäÖà (½â¾ö¿çÓò)


      server {
        listen       82;     
        server_name localhost;     
        
        #ÊÓÆµÖÐÐÄ     
        location / {    
          proxy_pass http://127.0.0.1:12000; 
          proxy_set_header Host $http_host;   
          add_header Access-Control-Allow-Origin *;         
          add_header Access-Control-Allow-Credentials true;           
          add_header Access-Control-Allow-Methods GET;      
        } 

        #ý×ʹÜÀíºǫ́¿çÓò     
        location ^~ /api/media/ {       
          proxy_pass http://127.0.0.1:9000/media/; 

          proxy_set_header Host $http_host;  
          add_header Access-Control-Allow-Origin *;         
          add_header Access-Control-Allow-Credentials true;           
          add_header Access-Control-Allow-Methods "GET,POST,OPTIONS";     
        }          
      }

      ¿ÉÒÔ·ÃÎÊ http://127.0.0.1:12000/#/media/upload »òÕß http://localhost:82/#/media/upload/ ²é¿´Ò³ÃæÐ§¹û¡£


      5. ý×Ê·þÎñ¶Ë±àд

      ·þÎñ¶ËÐèҪʵÏÖÈçϹ¦ÄÜ£º

      1¡¢ÉÏ´«Ç°¼ì²éÉÏ´«»·¾³

      ¼ì²éÎļþÊÇ·ñÉÏ´«£¬ÒÑÉÏ´«ÔòÖ±½Ó·µ»Ø¡£

      ¼ì²éÎļþÉÏ´«Â·¾¶ÊÇ·ñ´æÔÚ£¬²»´æÔÚÔò´´½¨¡£

      2¡¢·Ö¿é¼ì²é

      ¼ì²é·Ö¿éÎļþÊÇ·ñÉÏ´«£¬ÒÑÉÏ´«Ôò·µ»Øtrue¡£

      δÉÏ´«Ôò¼ì²éÉÏ´«Â·¾¶ÊÇ·ñ´æÔÚ£¬²»´æÔÚÔò´´½¨¡£

      3¡¢·Ö¿éÉÏ´«

      ½«·Ö¿éÎļþÉÏ´«µ½Ö¸¶¨µÄ·¾¶¡£

      4¡¢ºÏ²¢·Ö¿é

      ½«ËùÓзֿéÎļþºÏ²¢ÎªÒ»¸öÎļþ¡£

      ÔÚÊý¾Ý¿â¼Ç¼ÎļþÐÅÏ¢¡£

      ÓÉÓÚÉÏ´«¹ý³Ì¸´ÔÓ£¬¿ª·¢Ê±°´ÒµÎñÁ÷³Ì·Ö±ðʵÏÖ¡£

      ÅäÖÃ

      application.ymlÅäÖÃÉÏ´«ÎļþµÄ·¾¶£º



      xc-service-manage-media:
        upload-location: C:/school/video/  # Ã½×ʱ£´æÂ·¾¶
        ffmpeg-path: C:/Java_Soft/xczx/ffmpeg-20180227-fa0c9d6-win64-static/bin/ffmpeg.exe # ffmpeg·¾¶


      ¶¨ÒåDao

      ʹÓÃmybatis-plus



      @Mapper@Componentpublic interface FileMsgMapper extends BaseMapper<FileMsg> {}

      ¶¨Òåcontroller



      @RestController
      @RequestMapping("/media/upload")
      public class MediaUploadController {


          @Autowired
          MediaUploadService mediaUploadService;

          /**
           * ÎļþÉÏ´«Ç°µÄ×¢²á
           */

          @PostMapping("/register")
          public ResponseResult register(String fileMd5String fileNameLong fileSizeString mimetypeString fileExt) {

              return mediaUploadService.register(fileMd5, fileName, fileSize, mimetype, fileExt);

          }

          /**
           * ¼ì²â·Ö¿é
           *
           * @param fileMd5
           * @param chunk
           * @param chunkSize
           * @return
           */

          @PostMapping("/checkchunk")
          public ResponseResult checkchunk(String fileMd5Integer chunkInteger chunkSize) {
              return mediaUploadService.checkchunk(fileMd5, chunk, chunkSize);
          }

          /**
           * ÉÏ´«·Ö¿é
           *
           * @param file
           * @param fileMd5
           * @param chunk
           * @return
           */
          @PostMapping("/uploadchunk")
          public ResponseResult uploadchunk(MultipartFile fileString fileMd5Integer chunk) {
              return mediaUploadService.uploadchunk(file, fileMd5, chunk);
          }

          /**
           * ºÏ²¢·Ö¿é
           *
           * @param fileMd5
           * @param fileName
           * @param fileSize
           * @param mimetype
           * @param fileExt
           * @return
           */
          @PostMapping("/mergechunks")
          public ResponseResult mergechunks(String fileMd5String fileNameLong fileSizeString mimetypeString fileExt) {
              return mediaUploadService.mergechunks(fileMd5, fileName, fileSize, mimetype, fileExt);
          }
      }

      ¶¨Òåservice (ÂÔ)ÓÉÓÚ´úÂë¹ý¶à£¬Çë²Î¼ûÔ´Âë¡£

      ÏÖÔÚÊÓÆµÒѾ­Í¨¹ý¶ÏµãÐø´«µÄ·½Ê½£¬ÉÏ´«µ½ÁËÎÒÃǵÄý×Ê·þÎñÆ÷£¬ ½ÓÏÂÀ´¾ÍҪʹÓÃFFmpeg½«ÊÓÆµ×ª»»³ÉÁ÷ýÌå¡£

      6.ÊÓÆµ´¦Àí¼¼Êõ·½°¸

      ÈçºÎͨ¹ý³ÌÐò½øÐÐÊÓÆµ´¦Àí?

      ffmpegÊÇÒ»¸ö¿ÉÐеÄÊÓÆµ´¦Àí³ÌÐò£¬¿ÉÒÔͨ¹ýJavaµ÷ÓÃffmpeg.exeÍê³ÉÊÓÆµ´¦Àí¡£

      ÔÚjavaÖпÉÒÔʹÓÃRuntimeÀàºÍProcess BuilderÀàÁ½ÖÖ·½Ê½À´Ö´ÐÐÍⲿ³ÌÐò£¬¹¤×÷ÖÐÖÁÉÙÕÆÎÕÒ»ÖÖ¡£

      ±¾ÏîĿʹÓÃProcess BuilderµÄ·½Ê½À´µ÷ÓÃffmpegÍê³ÉÊÓÆµ´¦Àí¡£

      ¹ØÓÚProcess BuilderµÄ²âÊÔÈçÏ £º



      @Test
          public void testProcessBuilder(){
              ProcessBuilder processBuilder = new ProcessBuilder();
      //       processBuilder.command("ping","127.0.0.1");
             processBuilder.command("ipconfig");
              //½«±ê×¼ÊäÈëÁ÷ºÍ´íÎóÊäÈëÁ÷ºÏ²¢£¬Í¨¹ý±ê×¼ÊäÈëÁ÷¶ÁÈ¡ÐÅÏ¢
              processBuilder.redirectErrorStream(true);
              try {
                  //Æô¶¯½ø³Ì
                  Process start = processBuilder.start();
                  //»ñÈ¡ÊäÈëÁ÷
                  InputStream inputStream = start.getInputStream();
                  //ת³É×Ö·ûÊäÈëÁ÷
                  InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"gbk");
                  int len = -1;
                  char[] c = new char[1024];
                  StringBuffer outputString = new StringBuffer();
                  //¶ÁÈ¡½ø³ÌÊäÈëÁ÷ÖеÄÄÚÈÝ
                  while ((len= inputStreamReader.read(c))!=-1) {
                      String s = new String(c,0,len);
                      outputString.append(s);
                      System.out.print(s);
                  }
                  inputStream.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          @Test
          public void testFFmpeg(){
              ProcessBuilder processBuilder = new ProcessBuilder();
              //¶¨ÒåÃüÁîÄÚÈÝ
              List<Stringcommand = new ArrayList<>();
              command.add("D:\\Program Files\\ffmpeg-20180227-fa0c9d6-win64-static\\bin\\ffmpeg.exe");
              command.add("-i");
              command.add("E:\\ffmpeg_test\\1.avi");
              command.add("-y");//¸²¸ÇÊä³öÎļþ
              command.add("-c:v");
              command.add("libx264");
              command.add("-s");
              command.add("1280x720");
              command.add("-pix_fmt");
              command.add("yuv420p");
              command.add("-b:a");
              command.add("63k");
              command.add("-b:v");
              command.add("753k");
              command.add("-r");
              command.add("18");
              command.add("E:\\ffmpeg_test\\1.mp4");
              processBuilder.command(command);
              //½«±ê×¼ÊäÈëÁ÷ºÍ´íÎóÊäÈëÁ÷ºÏ²¢£¬Í¨¹ý±ê×¼ÊäÈëÁ÷¶ÁÈ¡ÐÅÏ¢
              processBuilder.redirectErrorStream(true);
              try {
                  //Æô¶¯½ø³Ì
                  Process start = processBuilder.start();
                  //»ñÈ¡ÊäÈëÁ÷
                  InputStream inputStream = start.getInputStream();
                  //ת³É×Ö·ûÊäÈëÁ÷
                  InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"gbk");
                  int len = -1;
                  char[] c = new char[1024];
                  StringBuffer outputString = new StringBuffer();
                  //¶ÁÈ¡½ø³ÌÊäÈëÁ÷ÖеÄÄÚÈÝ
                  while ((len= inputStreamReader.read(c))!=-1) {
                      String s = new String(c,0,len);
                      outputString.append(s);
                      System.out.print(s);
                  }
                  inputStream.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }

      ÎÒÃÇÒѾ­×¼±¸ºÃÁ˹¤¾ßÀࣺ

      Mp4VideoUtil.javaÍê³Éaviתmp4

      HlsVideoUtil.javaÍê³Émp4תhls

      ¿ÉÒÔÖ±½ÓʹÓá£

      6.1 ´¦ÀíÁ÷³Ì

      µ±ÊÓÆµºÏ²¢³É¹¦ºó

      °ÑÊÓÆµ´¦Àí³Ém3u8Á÷ýÌå

      °ÑÊÓÆµÐÅϢдµ½Êý¾Ý¿â

      ¾ßÌå´úÂ룺 Ôںϲ¢Íê³É·½·¨Öе÷ÓÃ


      @Value("${xc-service-manage-media.ffmpeg-path}")
          String ffmpeg_path;


          private void ChangeHLS(File mergeFile, String fileMd5) {

              // mp4 Îļþ±£´æÄ¿Â¼
              String fileFolderPath = getFileFolderPath(fileMd5);
              //Éú³ÉµÄmp4µÄÎļþÃû³Æ
              String mp4_name = fileMd5 + ".mp4";
              //Éú³ÉµÄmp4ËùÔڵķ¾¶
              String mp4folder_path = fileFolderPath;


              //´´½¨¹¤¾ßÀà¶ÔÏó
              Mp4VideoUtil mp4VideoUtil = new Mp4VideoUtil(ffmpeg_path, mergeFile.getAbsolutePath(), mp4_name, mp4folder_path);

              //½øÐд¦Àí
              String result = mp4VideoUtil.generateMp4();


              //4¡¢½«mp4Éú³Ém3u8ºÍtsÎļþ
              //String ffmpeg_path, String video_path, String m3u8_name,String m3u8folder_path
              //mp4ÊÓÆµÎļþ·¾¶
              String mp4_video_path = mp4folder_path + mp4_name;

              //m3u8_nameÎļþÃû³Æ
              String m3u8_name = fileMd5 + ".m3u8";
              //m3u8ÎļþËùÔÚĿ¼
              String m3u8folder_path = fileFolderPath + "hls/";

              HlsVideoUtil hlsVideoUtil = new HlsVideoUtil(ffmpeg_path, mp4_video_path, m3u8_name, m3u8folder_path);

              //Éú³Ém3u8ºÍtsÎļþ
              String tsResult = hlsVideoUtil.generateM3u8();

              //±£´æfileUrl£¨´Ëurl¾ÍÊÇÊÓÆµ²¥·ÅµÄÏà¶Ô·¾¶£©
              String filePath = fileFolderPath + "hls/" + m3u8_name;


              // ½«fileUrl ±£´æµ½Êý¾Ý¿â
              FileMsg fileMsg = new FileMsg();
              fileMsg.setFileId(fileMd5);
              fileMsg.setFileName(mergeFile.getName());
              fileMsg.setFilePath(filePath);
              fileMsg.setFileUrl(filePath.split("C:/school/video")[1]);

              fileMsgMapper.insert(fileMsg);


              //ÓÅ»¯:  Îļþ´¦Àí³É¹¦ºó, ¿ÉÒÔɾ³ýmp4Îļþ


          }

      ˵Ã÷£º

      mp4ת³Ém3u8ÈçºÎÅжÏת»»³É¹¦?

      µÚÒ»¡¢¸ù¾ÝÊÓÆµÊ±³¤À´ÅжÏ£¬Í¬mp4ת»»³É¹¦µÄÅжϷ½·¨¡£

      µÚ¶þ¡¢×îºó»¹ÒªÅжÏm3u8ÎļþÄÚÈÝÊÇ·ñÍêÕû¡£

      4 ²¥·ÅÆ÷

      4.1 ¼¼ÊõÑ¡ÐÍ

      ÊÓÆµ±àÂëºóҪʹÓò¥·ÅÆ÷¶ÔÆä½øÐнâÂë¡¢²¥·ÅÊÓÆµÄÚÈÝ¡£ÔÚwebÓ¦ÓÃÖг£ÓõIJ¥·ÅÆ÷ÓÐflash²¥·ÅÆ÷¡¢H5²¥·ÅÆ÷»òä¯ÀÀÆ÷²å¼þ²¥·ÅÆ÷£¬ÆäÖÐÒÔflashºÍH5²¥·ÅÆ÷×î³£¼û¡£

      flash²¥·ÅÆ÷£ºÈ±µãÊÇÐèÒªÔÚ¿Í»§»ú°²×°Adobe Flash Player²¥·ÅÆ÷£¬ÓŵãÊÇflash²¥·ÅÆ÷ÒѾ­ºÜ³ÉÊìÁË£¬²¢ÇÒä¯ÀÀÆ÷¶ÔflashÖ§³ÖÒ²ºÜºÃ¡£

      H5²¥·ÅÆ÷£º»ùÓÚh5×Ô´øvideo±êÇ©½øÐй¹½¨£¬ÓŵãÊǴ󲿷Öä¯ÀÀÆ÷Ö§³ÖH5£¬²»ÓÃÔÙ°²×°µÚÈý·½µÄflash²¥·ÅÆ÷£¬²¢ÇÒËæ×Åǰ¶Ë¼¼ÊõµÄ·¢Õ¹£¬h5¼¼Êõ»áÔ½À´Ô½³ÉÊì¡£

      ±¾ÏîÄ¿²ÉÓÃH5²¥·ÅÆ÷£¬Ê¹ÓÃVideo.js¿ªÔ´²¥·ÅÆ÷¡£

      Video.jsÊÇÒ»¿î»ùÓÚHTML5ÊÀ½çµÄÍøÂçÊÓÆµ²¥·ÅÆ÷¡£ËüÖ§³ÖHTML5ºÍFlashÊÓÆµ£¬ËüÖ§³ÖÔŲ́ʽ»úºÍÒÆ¶¯É豸Éϲ¥·ÅÊÓÆµ¡£Õâ¸öÏîÄ¿ÓÚ2010ÄêÖпªÊ¼£¬Ä¿Ç°ÒÑÔÚ40ÍòÍøÕ¾Ê¹Óá£

      ¹Ù·½µØÖ·£ºhttp://videojs.com/

      4.2 ÏÂÔØvideo.js

      Video.js£º https://github.com/videojs/video.js

      videojs-contrib-hls£º https://github.com/videojs/videojs-contrib-hls#installation

      (videojs-contrib-hlsÊDz¥·ÅhlsµÄÒ»¸ö²å¼þ)

      ʹÓÃÎĵµ£ºhttp://docs.videojs.com/tutorial-videojs_.html

      ±¾½Ì³ÌʹÓà video.js 6.7.3 °æ±¾£¬videojs-contrib-hls 5.14.1°æ±¾

      ½«×ÊÁÏÖÐÌṩµÄplugins¸³Öµµ½xc-ui-pc-videoÏîĿĿ¼ÏÂ

      ´î½¨Ã½Ìå·þÎñÆ÷


      4.3 ´î½¨Ã½Ìå·þÎñÆ÷

      Õý³£Ê¹ÓÃvideo.js²¥·ÅÊÓÆµÊÇͨ¹ýÒ»¸öÍøÒ³£¬Óû§Í¨¹ýä¯ÀÀÆ÷´ò¿ªÍøÒ³È¥²¥·ÅÊÓÆµ£¬ÍøÒ³ºÍÊÓÆµ¶¼´Óweb·þÎñÆ÷ÇëÇó¡£


      4.3.1 NginxýÌå·þÎñÆ÷

      NginxýÌå·þÎñÆ÷

      ¸ù¾ÝÉϱߵÄÁ÷³Ì£¬ÎÒÃÇÔÚýÌå·þÎñÆ÷Éϰ²×°Nginx£¬²¢ÅäÖÃÈçÏ £º



      # ÊÓÆµ¾²Ì¬×ÊÔ´
        location / {    
            alias   C:/CODE/JAVA/school/xc-ui-pc-video/;
            index  index.html index.htm;
        }   
      }

      4.4 ²âÊÔvideo.js

      1.°Ñ×ÊÁÏÖеÄvideo.html ¸´ÖƵ½ C:/CODE/JAVA/school/xc-ui-pc-video/ Èçͼ£º

      ²âÊÔvideo.js

      ÉÏÃæÒѾ­Ê¹ÓÃnginx ´úÀí C:/CODE/JAVA/school/xc-ui-pc-video/ Ŀ¼¡£ ËùÒÔ¿ÉÒÔͨ¹ýhttpÇëÇóÖ±½Ó·ÃÎÊvideo.htmlÒ³Ãæ

      °Ñsrc·¾¶ÐÞ¸ÄΪ×Ô¼ºµÄý×Ê·ÃÎÊ·¾¶

      ²âÊÔ£º

      Óû§´ò¿ªä¯ÀÀÆ÷ÊäÈë http://localhost:81/video.html ¡£¼´¿É´ò¿ªÊÓÆµ²¥·ÅÒ³Ãæ£¬²¢²¥·Å¡£


      ²ÂÄãϲ»¶£º

      µ¥ÀýÖÐÀÁºººÍ¶ñººÄ£Ê½µÄÇø±ð

      5·ÖÖÓÁ˽âÃÜÂëµÄ¼ÓÃܼÓÑδ¦Àí

      0 ·ÖÏíµ½£º
      ºÍÎÒÃÇÔÚÏß½»Ì¸£¡
      ¡¾ÍøÕ¾µØÍ¼¡¿¡¾sitemap¡¿