Flex4/Flash開發線上音樂播放器 , 含演示地址

Cheng發表於2014-07-12

要求

    • 必備知識

      本文要求基本瞭解 Adobe Flex程式設計知識和JAVA基礎知識。

    • 開發環境

      MyEclipse10/Flash Builder4.6/Flash Player11及以上

    • 演示地址

      演示地址

 
 

2014-07-09_1751281_thumb

 

傳統網路程式的開發是基於頁面的、伺服器端資料傳遞的模式,把網路程式的表現層建立於HTML頁面之上,而HTML是適合於文字的,傳統的基於頁面的系統已經漸漸不能滿足網路瀏覽者的更高的、全方位的體驗要求了。而富網際網路應用(Rich Internet Applications,縮寫為RIA)的出現就是為了解決這個問題。在HTML5釋出以前,RIA領域的技術解決方案一直相都是各展所長,並無爭議。Adobe體系中,Flash做不了的事情,Flex可以做到;.Net系決策者在選用RIA解決方案時,Silverlight是不二之選。隨著HTML 5橫空出世,Flex“易主”(這裡說的是Adobe將Flex捐給Apache),Silverlight被“雪藏”(這裡指微軟停止對Silverlight的更新),RIA領域的技術解決方案開始變得撲朔迷離。 HTML 5無疑是“明日之星”,蘋果公司前CEO賈伯斯對它讚賞有加,絕大多數智慧手機瀏覽器均支援HTML 5,基於HTML 5的網站也如雨後春筍般出現。這些似乎預示著HTML 5時代來臨,人們試圖讓決策者相信,Flash/Flex時代已經過去了,HTML 5才是RIA領域的最佳解決方案。那到底真相會是什麼呢? HTML 5其實也存在許多劣勢,並不完美。HTML 5的瀏覽器相容性問題(由於國內傳統IE瀏覽器佔了相當大的比重);要實現html5應用,還要寫CSS與JavaScript,增加了人員構成和開發成本,其編寫難度也要遠大於Flex。在較長一段時間內,HTML5是無法”替代”Flex技術的,也許最終HTML 5與Flex將成為是兩種截然不同的技術解決方案,所以,它們是互補的,而非替代。如對Flash/Flex/Html5還不瞭解,我到網際網路上找了一篇相關的文章和大家分享一下: 淺談 Flash/Flex/HTML5 技術選型

 

一,Flex4&BlazeDS&JAVA整合:

Myeclipse10.6+Flash Builder 4.6安裝配置

 

二,使用者介面設計:

  • 播放器介面的設計:

2014-07-10_1220305_thumb

 

  • 專輯製作介面的設計:

2014-07-10_122322410_thumb

 

三,資料庫設計:

2014-07-10_1149235_thumb

  • album(專輯表)建立語句:
CREATE TABLE `album` (
   `a_id` int(11) NOT NULL AUTO_INCREMENT,
   `a_name` varchar(20) NOT NULL DEFAULT '',
   `a_singer` varchar(20) NOT NULL DEFAULT '',
   `a_image` varchar(120) NOT NULL DEFAULT '',
   PRIMARY KEY (`a_id`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;
  • song(歌曲表)建立語句:
CREATE TABLE `song` (
   `s_id` int(11) NOT NULL AUTO_INCREMENT,
   `a_id` int(11) NOT NULL,
   `s_name` varchar(120) NOT NULL DEFAULT '',
   `s_source` varchar(150) NOT NULL DEFAULT '',
   PRIMARY KEY (`s_id`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;

 

四,前端程式碼物理實現(Flex4部分程式碼實現):

  • 播放器介面物理實現,通過在主程式中定義三個不同的自定義元件,”專輯””列表”“播放器控制皮膚”來構成整個播放器介面。

1,程式入口檔案:myMusicPlayer.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               minWidth="955" minHeight="600" skinClass="skinks.ApplicationSkin"
               xmlns:components="components.*"
               creationComplete="initApp()">
    <fx:Declarations>
        <!-- 將非可視元素(例如服務、值物件)放在此處 -->
        <s:RemoteObject id="albumListDist" destination="AlbumServerTaget"
                        result="albumListDist_resultHandler(event)"
                        fault="albumListDist_faultHandler(event)"/>
        
        <s:RemoteObject id="songListDist" destination="SongServerTaget"
                        result="songListDist_resultHandler(event)"
                        fault="songListDist_faultHandler(event)"/>
    </fx:Declarations>
    <fx:Metadata>
        [Event(name="changeitem",type="events.MyEvent")]   //通過 Event後設資料 定義自定義監聽事件
    </fx:Metadata>
    <fx:Script>
        <![CDATA[
            import events.MyEvent;
            import events.MyEvent2;
            import events.MyEvent3;
            
            import mx.collections.ArrayCollection;
            import mx.collections.ArrayList;
            import mx.controls.Alert;
            import mx.events.FlexEvent;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
            
            import valueObjects.Song;
            
            [Bindable]
            public var albums:ArrayCollection;
            public var listData:ArrayCollection=new ArrayCollection();
            private var musicSource:Object;
            private var albumSinger:String; //專輯歌手
            

            
            /**
             * 初始化函式
             */
            private function initApp():void{

                albumListDist.getList(); //呼叫服務端方法
                album.addEventListener(MyEvent3.CHANGEITEM,albumList_change_Handler3); //監聽自定義事件;

                
            /*     //將資料放入到值物件中
                for each(var temp:Object in data[0]){
                    var song:Song=new Song();
                    song.singer=temp.singer;
                    song.song=temp.song;
                    song.musicSource=temp.musicSource;
                    listData.addItem(song);
                }  
                //列表自動初始化第一個專輯資料繫結
                list.data=listData;
                //專輯繫結資料
                album.data=Album;
                player.musicItem=Object(listData[0]);
                player.musicNum=listData.length;   
                //Alert.show(data[0].length);
                */
            }        
            
            /**
             * 重新選擇專輯後呼叫
             */
            private function albumList_change_Handler3(event:MyEvent3):void{
                albumSinger=event.albumItem.a_singer;
                songListDist.getSongsById(event.albumItem.a_id); //通過專輯ID請求專輯的資料
                
            }
            
            
            /**
             *結果函式     albumListDist.getList()  獲取專輯列表
             */
            protected function albumListDist_resultHandler(event:ResultEvent):void
            {
                
                albums=event.result as ArrayCollection;
                album.data=albums; //繫結專輯資料
                albumSinger=albums[0].a_singer;  //獲取第一個專輯裡歌手資訊
                songListDist.getSongsById(albums[0].a_id); //請求第一個專輯的資料
                
                
            }
            
            protected function albumListDist_faultHandler(event:FaultEvent):void{
                //Alert.show(event.message.toString());
            }
            

            
            /**
             * 結果函式 songListDist.getSongsById(albums[0].a_id); 請求第一個專輯的資料
             */
            protected function songListDist_resultHandler(event:ResultEvent):void
            {
            
                list.data=event.result as ArrayCollection;
                player.musicItem=event.result[0] as Object;   //歌曲例項
                player.musicNum=ArrayCollection(event.result).length; //專輯含歌曲數量 專輯長度
                player.albumSinger=albumSinger;
                
                
            }
            
            protected function songListDist_faultHandler(event:FaultEvent):void{}
            
            
            
        ]]>
    </fx:Script>
    
    <!--程式主題-->
    <s:Group horizontalCenter="0" verticalCenter="0">
        <!--背景圖片-->
        <s:BitmapImage  width="1078" smooth="true"
                       source="@Embed('/assets/images/contentBg.png')"/>
            <!--專輯-->
            <components:Album id="album" x="220" y="70" width="100%" height="100%"/>
            <!--列表-->
            <components:List  id="list"   width="220" height="605" />
            <!--播放器控制皮膚-->
            <components:Player id="player" />

    </s:Group>
</s:Application>

2,自定義“專輯”元件:Album.mxml

2014-07-10_1329245_thumb

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx"
         creationComplete="group1_creationCompleteHandler(event)">
    
    <fx:Declarations>
        <!-- 將非可視元素(例如服務、值物件)放在此處 -->
    </fx:Declarations>
    <fx:Metadata>
        
        [Event(name="changeitem3",type="events.MyEvent3")] 
    </fx:Metadata>
    <fx:Script>
        <![CDATA[
            import events.MyEvent2;
            import events.MyEvent3;
            
            import mx.collections.ArrayCollection;
            import mx.controls.Alert;
            import mx.events.FlexEvent;
            [Bindable]
            public var data:ArrayCollection;
            
            /**
             * 初始化函式
             */
            protected function group1_creationCompleteHandler(event:FlexEvent):void
            {
                list.addEventListener(MouseEvent.DOUBLE_CLICK,albumDoubleClick);
                
            }
            
            
            /**
             * 雙擊事件
             */
            private function albumDoubleClick(event:MouseEvent):void{
                
                dispatchEvent(new MyEvent3("changeitem3",list.selectedItem)); //分配事件  此事打List元件中呼叫
            }
            
        ]]>
    </fx:Script>
    <s:BitmapImage  left="-20" top="15"  source="@Embed('/assets/images/RasterizedItems3.png')"
                    />
    <s:List id="list" left="0" top="43" dataProvider="{data}" itemRenderer="components.AlbumItem" skinClass="skinks.MyAlbums"
            doubleClickEnabled="true"
            requireSelection="true"
            selectedIndex="0">
        <s:layout>
            <s:TileLayout paddingTop="50" paddingLeft="70" verticalGap="40" horizontalGap="40" orientation="rows"
                          requestedColumnCount="4"
/>
        </s:layout>
    </s:List>
</s:Group>

 

3,自定義“列表”元件:List.mxml

2014-07-10_1329455_thumb

<?xml version="1.0" encoding="utf-8"?>
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                      xmlns:s="library://ns.adobe.com/flex/spark" 
                      xmlns:mx="library://ns.adobe.com/flex/mx"
                      creationComplete="init(event)">
    <fx:Declarations>
        <!-- 將非可視元素(例如服務、值物件)放在此處 -->
    </fx:Declarations>
    <fx:Metadata>
        
        [Event(name="changeitem",type="events.MyEvent")]  
    </fx:Metadata>
    <fx:Script>
        <![CDATA[
            import events.MyEvent;
            import events.MyEvent2;
            
            import mx.collections.ArrayCollection;
            import mx.collections.ArrayList;
            import mx.controls.Alert;
            import mx.events.FlexEvent;
            
            [Bindable]
            public var data:ArrayCollection;
            
            
    
            
            protected function init(event:FlexEvent):void
            {
                list.addEventListener(MouseEvent.DOUBLE_CLICK,itemDoubleClick);
            
                
            }
            
            
            private function itemDoubleClick(event:MouseEvent):void{
                var temp:Object=list.selectedItem;
                dispatchEvent(new MyEvent("changeitem",temp));
            
            }
            
            
            
        ]]>
    </fx:Script>
    
    <s:BitmapImage  height="100%" 
                    source="@Embed('/assets/images/RasterizedItems2.png')"/>
    <s:VGroup top="110" left="0" right="0" bottom="0">
        <s:Label color="#FFFFFF" fontFamily="微軟雅黑" fontSize="13" paddingLeft="30"
                 text="歌單"/>
        <s:List id="list"
                dataProvider="{data}" 
                itemRenderer="components.ListItem" 
                skinClass="skinks.list.SongsList"    
                doubleClickEnabled="true"
                requireSelection="true"
                selectedIndex="0"
                
                height="100%"
                width="100%" >
            <s:layout>
                <s:VerticalLayout gap="0" paddingLeft="0" />
            </s:layout>
        </s:List>
    </s:VGroup>
    
    
</s:SkinnableContainer>

4,自定義“播放器控制皮膚”元件:Player.mxml

2014-07-10_1330085_thumb

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" 
         creationComplete="init()">
    <fx:Declarations>
        <!-- 將非可視元素(例如服務、值物件)放在此處 -->
    </fx:Declarations>
    <fx:Metadata>  
        
    </fx:Metadata>
    <fx:Script>
        <![CDATA[
            import events.MyEvent;
            
            import mx.controls.Alert;
            import mx.events.FlexEvent;
            
            import utils.Tool4DateTime;
            
            
            
            /**
             * 伺服器IP地址
             */
            private var serverIP:String="http://localhost:8080";
            

            
            /**
             * List物件
             */
            public var MusicList:List;
            
            /**
             * musicItem Object  音樂資訊物件
             */
            [Bindable]
            public var musicItem:Object;
             
            /**
             * 列表歌曲數量
             */
            public var musicNum:int;
            
            
            /**
             * 歌手名稱
             */
            [Bindable]
            public var albumSinger:String;
            
            
            
            /**
             * 播放器音量 
             */
            private var currentVolum:Number =0.5;
            /**
             * 正在播放的音樂的URL字串
             * 從主程式中獲得 player.currentMusicUrlString=musicSource;
             */
            public var currentMusicUrlString:String;
            /**
             * 正在播放的音樂的URLRequest 
             */
            private var currentMusicUrlRequest:URLRequest;
            /**
             * 正在播放的音樂的Sound 
             */
            private var currentMusicSound:Sound;
            /**
             * 正在播放的音樂的SoungChannel 
             * SoundChannel 類控制應用程式中的聲音。每個聲音均分配給一個聲道,而且應用程式可以具有混合在一起的多個聲道。SoundChannel 類包含 stop() 方法、用於監控聲道幅度(音量)的屬性以及用於對聲道指定 SoundTransform 物件的屬性。 
             */
            private var currentMusicChannel:SoundChannel;
            /**
             * 正在播放的音樂的 SoundTransform
             * SoundTransform 類包含音量和平移的屬性。
             */
            private var currentMusicTransform:SoundTransform;
            /**
             * 正在播放的音樂的播放進度引數 
             */
            private var currentMusicPosition:int =0;
            /**
             * 正在播放的音樂的總時間 
             */
            private var currentMusicTotleTime:Number =0;
            /**
             * 音樂是否正在播放 
             */
            private var isplaying:Boolean = false;
            
            
            
            
            

            
            private function init():void{
                playAndPause.addEventListener(MouseEvent.CLICK,musicPlay); //播放按鈕
                previous.addEventListener(MouseEvent.CLICK,playPrevious); //上一首
                next.addEventListener(MouseEvent.CLICK,playNext); //上一首
                playingProcess.addEventListener(Event.CHANGE,playingProcess_changeHandler); //進度條滾動事件
                volumeSlider.addEventListener(Event.CHANGE,volumeSlider_changeHandler); //音量條滾動事件
                //監聽自定義事件
                MusicList=parentApplication.list;  //設定List物件
                MusicList.addEventListener(MyEvent.CHANGEITEM,playerList_change_Handler); //監聽自定義事件
            }
            
            
            private function musicPlay(event:MouseEvent):void{
                if(!isplaying){  //播放  false
                    //此狀態為 啟動播放器 然後點選播放按鈕 狀態(空狀態)    
                    if(currentMusicSound==null&&currentMusicChannel ==null){
                        currentMusicUrlString=serverIP+musicItem.s_source;
                        currentMusicUrlRequest =new URLRequest(currentMusicUrlString); 
                        currentMusicSound = new Sound();
                        currentMusicSound.load(currentMusicUrlRequest);
                        currentMusicSound.addEventListener(Event.COMPLETE,load_CompleteHandler);
                        currentMusicChannel = currentMusicSound.play();//開始播放
                        timer_GetCurrentPositionHandler();//同步更新已經播放的時間的計時器
                        //currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自動播放下一首
                    }else{//此狀態為 暫停後點選播放按鈕 狀態
                        currentMusicChannel = currentMusicSound.play(currentMusicPosition);
                    }
                    isplaying=true;
                }else{    //暫停
                    //此狀態為 播放過程中點選 暫停按鈕 狀態
                    currentMusicPosition = currentMusicChannel.position;//記錄暫停位置
                    currentMusicChannel.stop();//暫停
                    isplaying=false;
                }
                
                currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自動播放下一首
                
                
            }
            
            
            /**
             * 自動播放下一首 
             * @param event
             * 
             */
            protected function autoPlayNext(event:Event):void{//過濾引數問題
                
                
                
                if(parentApplication.list.list.selectedIndex>=musicNum-1 ){
                    parentApplication.list.list.selectedIndex = 0;
                }else{
                    parentApplication.list.list.selectedIndex += 1;
                }
                
                if(currentMusicSound!=null&&currentMusicChannel!=null){
                    currentMusicChannel.stop();//暫停
                }
                clearPar();
                musicItem=parentApplication.list.list.selectedItem;
                
                currentMusicUrlString=serverIP+musicItem.s_source;
                currentMusicUrlRequest =new URLRequest(currentMusicUrlString);
                currentMusicSound = new Sound();
                currentMusicSound.load(currentMusicUrlRequest);
                currentMusicSound.addEventListener(Event.COMPLETE,load_CompleteHandler);
                playAndPause.selected=true;
                isplaying =true;
                currentMusicChannel = currentMusicSound.play();//開始播放
                timer_GetCurrentPositionHandler();//同步更新已經播放的時間的計時器
                currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自動播放下一首

            }
            
            
            
            /**
             * 播放上一首
             */
            protected function playPrevious(event:MouseEvent):void
            {
                parentApplication.list.list.selectedIndex--;
                if(parentApplication.list.list.selectedIndex<0 ){
                    parentApplication.list.list.selectedIndex = musicNum-1;
                }
                
                if(currentMusicSound!=null&&currentMusicChannel!=null){
                    currentMusicChannel.stop();//暫停
                }
                clearPar();
                musicItem=parentApplication.list.list.selectedItem;
                
                currentMusicUrlString=serverIP+musicItem.s_source;
                currentMusicUrlRequest =new URLRequest(currentMusicUrlString);
                currentMusicSound = new Sound();
                currentMusicSound.load(currentMusicUrlRequest);
                currentMusicSound.addEventListener(Event.COMPLETE,load_CompleteHandler);
                playAndPause.selected=true;
                isplaying =true;
                currentMusicChannel = currentMusicSound.play();//開始播放
                timer_GetCurrentPositionHandler();//同步更新已經播放的時間的計時器
                currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自動播放下一首
                
                
            }
            
            
            /**
             *  播放下一首
             */
            protected function playNext(event:MouseEvent):void
            {
                parentApplication.list.list.selectedIndex++;
                if(parentApplication.list.list.selectedIndex>musicNum-1 ){
                    parentApplication.list.list.selectedIndex = 0;
                }
                
                if(currentMusicSound!=null&&currentMusicChannel!=null){
                    currentMusicChannel.stop();//暫停
                }
                clearPar();
                musicItem=parentApplication.list.list.selectedItem;
                
                currentMusicUrlString=serverIP+musicItem.s_source;
                currentMusicUrlRequest =new URLRequest(currentMusicUrlString);
                currentMusicSound = new Sound();
                currentMusicSound.load(currentMusicUrlRequest);
                currentMusicSound.addEventListener(Event.COMPLETE,load_CompleteHandler);
                playAndPause.selected=true;
                isplaying =true;
                currentMusicChannel = currentMusicSound.play();//開始播放
                timer_GetCurrentPositionHandler();//同步更新已經播放的時間的計時器
                currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自動播放下一首
                
                
            }
            
            
            
        
            
            private function playerList_change_Handler(event:MyEvent):void{

                if(currentMusicSound!=null&&currentMusicChannel!=null){
                    currentMusicChannel.stop();//暫停
                }
                clearPar();
                musicItem=event.musicItem;
                currentMusicUrlString=serverIP+musicItem.s_source;
                currentMusicUrlRequest =new URLRequest(currentMusicUrlString);
                currentMusicSound = new Sound();
                currentMusicSound.load(currentMusicUrlRequest);
                currentMusicSound.addEventListener(Event.COMPLETE,load_CompleteHandler);
                playAndPause.selected=true;
                isplaying =true;
                currentMusicChannel = currentMusicSound.play();//開始播放
                timer_GetCurrentPositionHandler();//同步更新已經播放的時間的計時器
                currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自動播放下一首

            }
            
        
            /**
             * 清除引數
             * currentMusicSound = null; 
             * currentMusicChannel = null;
             * currentMusicPosition = 0; 
             * 
             */
            private function clearPar():void{
                currentMusicSound = null;
                currentMusicChannel = null;
                currentMusicPosition = 0; 
            }
            
            
            
            
            
            
            /**
             * 正在播放的歌曲的總時長 
             */
            private var len:int;
            
            /**
             * 檔案載入完成 能讀取到音樂的總時長 
             * @param event
             * 
             */
            protected function load_CompleteHandler(event:Event):void{
                len = currentMusicSound.length;
                totalTime.text = Tool4DateTime.millionSecond2MinuteSecond(len);
            }
            
            /**
             * 同步更新已經播放的時間的計時器
             * 
             */
            protected function timer_GetCurrentPositionHandler():void{
                var clock:Timer = new Timer(100,int(len/1000/60*10));//每0.1秒更新一次
                clock.start();
                clock.addEventListener(TimerEvent.TIMER,showTime);
            }
            
            /**
             * 顯示已經播放的總時間 
             * @param event
             * 
             */
            protected function showTime(event:Event):void{
                playingProcess.maximum = int(len/1000)*10;//最大值
                playingProcess.value = int(currentMusicPosition/1000*10); //當前值
                currentMusicPosition = currentMusicChannel.position;
                playedTime.text = Tool4DateTime.millionSecond2MinuteSecond(currentMusicPosition);
            }
            
            
            /**
             * 播放進度條 可以拖動
             * @param event
             * 
             */
            protected function playingProcess_changeHandler(event:Event):void{
                if(currentMusicChannel!=null){
                    currentMusicPosition = playingProcess.value*1000/10;//當前音樂播放進度
                    currentMusicChannel.stop();
                    currentMusicChannel = currentMusicSound.play(currentMusicPosition);
                    isplaying=true;
                    
                    playAndPause.selected=true;
                    currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自動播放下一首

                }else{
                    playingProcess.value=0;
                }
            }
            
            /**
             * 音量調節
             * @param event
             * 
             */
            protected function volumeSlider_changeHandler(event:Event):void{
                if(currentMusicChannel != null){//正在播放時調節音量
                    currentMusicTransform = currentMusicChannel.soundTransform;
                    currentMusicTransform.volume = volumeSlider.value/10;
                    currentMusicChannel.soundTransform = currentMusicTransform;
                    currentVolum = currentMusicTransform.volume;    
                }
                currentVolum = volumeSlider.value/10;
            }
            
            
            
            
            
            
            
            
            
            
            
        ]]>
    </fx:Script>
    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>
    <!--背景圖片-->
    <s:BitmapImage  smooth="true"
                    source="@Embed('/assets/images/headBg.png')"/>
    <s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" >
        <!--播放按鈕-->
        <s:HGroup  left="35" bottom="15" verticalAlign="middle"  >
            <s:Button skinClass="skinks.playercontrol.PreviousButton" id="previous"   /> 
            <s:ToggleButton id="playAndPause" skinClass="skinks.playercontrol.PlayAndPause"  />
            <s:Button  skinClass="skinks.playercontrol.NextButton"  id="next"/>
        </s:HGroup>
        <!--音量條-->
        <s:HGroup left="200" bottom="15" height="50" gap="10" verticalAlign="middle">
            <s:BitmapImage  source="@Embed('/assets/images/MuteButton.png')"/>
            <s:HSlider id="volumeSlider" skinClass="skinks.playercontrol.volume.HSliderSkin" maximum="10" stepSize="1" value="5" />
            <s:BitmapImage smooth="true"
                           source="@Embed('/assets/images/RasterizedItems10.png')"/>
        </s:HGroup>
        <s:BitmapImage smooth="true" source="@Embed('/assets/images/Shape 14.png')"
                       x="365" y="2"/>
        <!--進度條和歌曲資訊-->
        <s:VGroup left="372" bottom="25" horizontalAlign="center" >
            <s:Label text="{musicItem.s_name}"
                     color.normal="#D6D3D3" fontFamily.normal="微軟雅黑" fontSize.normal="13"
                     fontWeight.normal="bold"/>
            <s:Label text="{albumSinger}"
                     color.normal="#D6D3D3" fontFamily.normal="微軟雅黑" fontSize.normal="11"/>
            <s:HGroup>
                <s:Label id="playedTime" text="00:00"
                         color.normal="#D6D3D3" fontFamily.normal="微軟雅黑"/>
                <s:ScrubBar id="playingProcess" skinClass="skinks.playercontrol.scrubbar.ScrubBar"/>
                <s:Label id="totalTime" text="00:00"
                         color.normal="#D6D3D3" fontFamily.normal="微軟雅黑"/>
            </s:HGroup>
        </s:VGroup>
    </s:Group>
</s:Group>

關於flex操作音訊檔案,可以參考我之前做的一個簡單音樂播放器例項:

部落格中 Flex4/Flash mp3音樂播放器例項 含演示地址

o_2014-03-13_1310385_thumb

 

  • 專輯製作外掛物理實現、

2014-07-10_122322411_thumb

MyUpload3.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
               skinClass="skinks.ApplicationSkink"
               creationComplete="init()">
    <fx:Style source="assets/styles/main.css"/>
    <fx:Declarations>
        <!-- 將非可視元素(例如服務、值物件)放在此處 -->
    
    </fx:Declarations>

    <fx:Script>
        <![CDATA[
            import components.Album;
            import components.GridHeaderRenderer;
            import components.MultiFileUpload;
            
            import events.MyEvent;
            
            import mx.collections.ArrayCollection;
            import mx.collections.ArrayList;
            import mx.controls.Alert;
            import mx.utils.StringUtil;
            
            import spark.components.gridClasses.GridColumn;
            [Bindable]
            private var data=new ArrayCollection([
                {id:"1",song:"心願",sf:".mp3"},
                {id:"2",song:"心願",sf:".mp3"},
                {id:"3",song:"心願",sf:".mp3"},
                {id:"4",song:"心願",sf:".mp3"},
                {id:"4",song:"心願",sf:".mp3"}
            ]);
            
            public var album:Album;  //專輯資訊上傳物件
            public var multiFileUpload:MultiFileUpload;  //音樂檔案上傳物件
            
            public var imageTypes:FileFilter = new FileFilter("Images (*.jpg; *.jpeg; *.gif; *.png)" ,"*.jpg; *.jpeg; *.gif; *.png");
            public var imagefilesToFilter:Array = new Array(imageTypes); //圖片過濾陣列
            public var ImageUploadDestination:String = "http://localhost:8080/MyUpload4/AlbumAdd";  //專輯資訊上傳地址

            
            public var musicTypes:FileFilter = new FileFilter("Music Files (*.mp3)","*.mp3");
            public var filesToFilter:Array = new Array(musicTypes); //音樂過濾陣列
            public var uploadDestination:String = "http://localhost:8080/MyUpload4/FileUploadServlet";  //專輯資訊上傳地址


            
            
            
            private function init():void{
                
                album=new Album(albumName,singer,ImageUploadDestination,imagefilesToFilter,img,create);
                album.addEventListener(MyEvent.COMPLETE,albumUpload);
                
                
                //初始化資料列表頭
                var _nameColumn = new GridColumn;
                var _typeColumn = new GridColumn;
                var _sizeColumn = new GridColumn;
                
                
                _nameColumn.headerText= "File";
                _nameColumn.headerRenderer=new ClassFactory(GridHeaderRenderer);
                
                _typeColumn.headerText = "File Type";
                _typeColumn.width = 80;
                _typeColumn.headerRenderer=new ClassFactory(GridHeaderRenderer);
                
                _sizeColumn.headerText = "File Size";
                _sizeColumn.width = 150;
                _sizeColumn.headerRenderer=new ClassFactory(GridHeaderRenderer);
                
                var _columns = new ArrayList([_nameColumn,_typeColumn,_sizeColumn]);
                filesDG.columns=_columns;
            }
            
            private function albumUpload(e:MyEvent):void{
            
                
                var postVariables:URLVariables = new URLVariables;
                postVariables.id = e.data;

                
                
                
    
                multiFileUpload = new MultiFileUpload(
                    filesDG,
                    browseBTN,
                    clearButton,
                    delButton,
                    upload_btn,
                    progressbar,
                    uploadDestination,
                    postVariables,
                    10240000,
                    filesToFilter
                );
                
            //    var test=filesDG.columns.getItemAt(0);
                
                
                
                
            }
            
            
        
        
            
            
        ]]>
    </fx:Script>
    <s:Group width="460" verticalCenter="0" horizontalCenter="0">
        <s:layout>
            <s:VerticalLayout verticalAlign="middle" horizontalAlign="center"/>
        </s:layout>
        
        <!--專輯資訊-->
        <s:Group width="100%">    
            <s:Button id="create" 
                      right="0" width="60" height="150" label="建立專輯" 
                      enabled="true"
                      skinClass="skinks.ButtonSkin1"/>
            <s:SkinnableContainer  width="400" height="150" skinClass="skinks.SkinnableContainer">
                <s:Image id="img" left="10" top="10" width="130" height="130" scaleMode="zoom" smooth="true"
                         source="assets/images/album.png"/>
                <s:VGroup width="100%" height="100%" top="10" left="140" bottom="10" right="10" gap="0">
                    <s:HGroup width="100%" height="100%" verticalAlign="middle" paddingLeft="10">
                        <s:Label width="50" color="#FFFFFF" fontFamily="微軟雅黑" fontSize="14"
                                 text="專輯名" textAlign="right"/>
                        <s:TextInput id="albumName" width="180" height="30"  borderVisible="false" fontFamily="微軟雅黑"
                                     fontSize="14"/>
                    </s:HGroup>
                    <s:HGroup width="100%" height="100%" verticalAlign="middle" paddingLeft="10">
                        <s:Label width="50" color="#FFFFFF" fontFamily="微軟雅黑" fontSize="14" text="歌手"
                                 textAlign="right"/>
                        <s:TextInput id="singer" width="180" height="35" borderVisible="false" fontFamily="微軟雅黑"
                                     fontSize="14"/>
                    </s:HGroup>
                </s:VGroup>
                
            </s:SkinnableContainer>
        </s:Group>
        
        
        <!--資料列表-->
        <s:DataGrid id="filesDG" width="460" color="#FFFFFF"  fontFamily="微軟雅黑" fontSize="13"
                    requestedRowCount="4" rowHeight="70" skinClass="skinks.DG">
            <!--<s:columns>
                <s:ArrayList>
                    <s:GridColumn dataField="id" headerText="#" headerRenderer="components.GridHeaderRenderer"  itemRenderer="components.GridItemRenderer"></s:GridColumn>
                    <s:GridColumn dataField="song" headerText="歌曲" headerRenderer="components.GridHeaderRenderer"  itemRenderer="components.GridItemRenderer"></s:GridColumn>
                    <s:GridColumn dataField="sf" headerText="字尾" headerRenderer="components.GridHeaderRenderer" itemRenderer="components.GridItemRenderer"></s:GridColumn>
                </s:ArrayList>
            </s:columns>-->
        </s:DataGrid>
        
        
        <mx:ProgressBar 
            id="progressbar"
            width="100%" 
            height="15" 
            labelPlacement="center"
            barSkin="skinks.ProgressBar.CustomProgressSkin"
            trackSkin="skinks.ProgressBar.CustomProgressBarTrackSkin"
            
            color="0xFFFFFF"
            minimum="0" 
            visible="true"
            maximum="100" 
            label="CurrentProgress 0%" 
            direction="right"
            mode="manual" 
            />
        
        <s:HGroup gap="0">
            <s:Button id="browseBTN" label="瀏覽" fontFamily="微軟雅黑"/>
            <s:Button id="upload_btn" label="上傳" fontFamily="微軟雅黑"/>
            <s:Button  id="delButton" label="移除" fontFamily="微軟雅黑"/>
            <s:Button id="clearButton" label="移除全部" fontFamily="微軟雅黑"/>
        </s:HGroup>

    </s:Group>
    
</s:Application>

關於檔案上傳部分,是根據MultiFile Upload外掛,通過自定義UI元件皮膚完成,可以參考我之前的一個修改例項:

Flex4/Flash多檔案上傳(帶進度條)例項分享

0710172747118075_thumb

五,後端程式碼物理實現(JAVA部分程式碼物理實現):

AlbumDao.java

package com.dao;

import java.awt.List;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import com.bean.Album;

import com.resource.JDBCUtilSingle;

public class AlbumDao {
        
    /**
     * 插入專輯資訊 返回ID號
     * @param a_name
     * @param a_singer
     * @param a_image
     * @return
     */
    public int addAlbum(String a_name,String a_singer,String a_image){
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet rs=null;
        connection=JDBCUtilSingle.getInitJDBCUtil().getConnection();
        int id=0;
         
        try {
            //專輯資訊插入
            String sql="insert into album(a_name,a_singer,a_image) values(?,?,?)";
            statement=connection.prepareStatement(sql);
            statement.setString(1,a_name);
            statement.setString(2,a_singer);
            statement.setString(3,a_image);
            //System.out.println(sql);
            statement.executeUpdate(); 
            //獲取插入ID
            rs = statement.getGeneratedKeys();
            rs.next();         
            id = rs.getInt(1);  
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        JDBCUtilSingle.getInitJDBCUtil().closeConnection(rs, statement, connection);
        return id;
    }
    
    
    
    
    
    /**
     * 獲取所有專輯資訊
     * @return  返回專輯列表
     */
    public ArrayList selectAlbum(){
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet rs=null;
        connection=JDBCUtilSingle.getInitJDBCUtil().getConnection();
        ArrayList albums=new ArrayList();
        try {
            //專輯資訊插入
            String sql="select * from album";
            statement=connection.prepareStatement(sql);
            rs=statement.executeQuery();
             while(rs.next()){
                    albums.add(new Album(rs.getInt("a_id"), rs.getString("a_name"), rs.getString("a_singer"), rs.getString("a_image")));
             }
            
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally{
            JDBCUtilSingle.getInitJDBCUtil().closeConnection(rs, statement, connection);
        }
        return albums;
    }
}

SongDao.java

package com.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import com.bean.Album;
import com.bean.Song;
import com.resource.JDBCUtilSingle;

public class SongDao {
    
    
    public int addSongs(int a_id,String s_name,String s_source){
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet rs=null;
        connection=JDBCUtilSingle.getInitJDBCUtil().getConnection();
        int tag=0;
        try {
            String sql="insert into song(a_id,s_name,s_source) values(?,?,?)";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,a_id);
            statement.setString(2,s_name);
            statement.setString(3,s_source);
            tag=statement.executeUpdate();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        JDBCUtilSingle.getInitJDBCUtil().closeConnection(rs, statement, connection);
        return tag;
    }
    
    
    public ArrayList getSongs(int a_id){
        ArrayList songs=new ArrayList();
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet rs=null;
        connection=JDBCUtilSingle.getInitJDBCUtil().getConnection();
        try {
            String sql="select * from song where a_id="+a_id;
            statement=connection.prepareStatement(sql);
            rs=statement.executeQuery();
            while(rs.next()){
                songs.add(new Song(rs.getInt("s_id"), rs.getInt("a_id"), rs.getString("s_name"), rs.getString("s_source")));
         }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally{
            
            JDBCUtilSingle.getInitJDBCUtil().closeConnection(rs, statement, connection);
        }

        return songs;
        
    }
}

 

好吧,就寫到這裡了,因為程式碼是較早之前寫的了,由於學校放假,閒來沒事,就那之前的程式碼翻看了一遍,由於時間久遠,也沒寫什麼註釋,在程式碼的語法和程式邏輯上,自己也硬是看了半天才回過神來。現在在程式碼中加了一些註釋,新增了一些歌曲內容,已上傳到測試空間中,歡迎大家來測試。由於本人水平有限,如文章在表述或程式碼方面有何不妥之處,歡迎批評指正。

 

你可能還對以下關於Flex的文章內容還感興趣:

 

如以上文章或連結對你有幫助的話,別忘了在文章結尾處輕輕點選一下 “還不錯”按鈕或到頁面右下角點選 “贊一個” 按鈕哦。你也可以點選頁面右邊“分享”懸浮按鈕哦,讓更多的人閱讀這篇文章。

作者:Li-Cheng
由於本人水平有限,文章在表述和程式碼方面如有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論哦。你也可以關注我,一起學習哦!

相關文章