• 1510 阅读
  • 6 回复

.net下输出flash的类库——swfdotnet

视频在线上传+队列转换FLV+水印+捉图+修复+获时+转3GP(API语言不限,开视频站必备!)
SwfDotNet是C#编写的,作者的C#水平,真是令我佩服。这是个特别好的读写Swf文件的库。
下载:http://sourceforge.net/projects/swfdotnet/files/

http://www.codeproject.com/Articles/16834/How-to-create-a-simple-SWF-decompiler-with-the-Swf

源文件及BIN下载:
swfdotnet-1.0-RC1.zip (您是游客您没有权限下载)


SwfDotNet.IO.chm (您是游客您没有权限下载)
本帖最后由 张小鱼 于 2012-03-07 14:59 编辑
小鱼的淘宝店铺-多多支持哇
视频在线上传+队列转换FLV+水印+捉图+修复+获时+转3GP(API语言不限,开视频站必备!)

呵呵~今天终于找到了.net下输出flash的类库——swfdotnet
一款意大利某公司出品的类库,目前的版本是0.68 beta.真爽!!虽然没有中文帮助,甚至连英文帮助都没有。可是这点小困难从来都是难不倒小火同学的哦!
有Sample,但是意大利语的注释~看不懂~但是类和方法的命名非常好~
YES~~
贴一个第一次输出swf的代码:

static void initswf()
 {
  Movie movie =new Movie(1024,768,new RGB(0,0,0)); //声明一个swf影片
  movie.FrameRate=30;                               //帧速率

  Rectangle rct =new Rectangle(1024,768,0);
  TagDefineBitsJPEG2 jpeg =new TagDefineBitsJPEG2("image/1.jpg");
  rct.FillStyle=new FillStyle(jpeg,BitmapFill.TiledBitmap); //用图片填充该矩形
  Rectangle rct1 =new Rectangle(1024,768,0);
  TagDefineBitsJPEG2 jpeg1 =new TagDefineBitsJPEG2("image/2.jpg");
  rct1.FillStyle=new FillStyle(jpeg1,BitmapFill.TiledBitmap); //用图片填充该矩形
  Rectangle rct2 =new Rectangle(1024,768,0);
  TagDefineBitsJPEG2 jpeg2 =new TagDefineBitsJPEG2("image/3.jpg");
  rct2.FillStyle=new FillStyle(jpeg2,BitmapFill.TiledBitmap); //用图片填充该矩形
  Rectangle rct3=new Rectangle(1024,768,0);
  TagDefineBitsJPEG2 jpeg3 =new TagDefineBitsJPEG2("image/4.jpg");
  rct3.FillStyle=new FillStyle(jpeg3,BitmapFill.TiledBitmap); //用图片填充该矩形
  movie.Define(jpeg);
  movie.Define(rct);
  movie.Define(jpeg1);
  movie.Define(rct1);
  movie.Define(jpeg2);
  movie.Define(rct2);
  movie.Define(jpeg3);
  movie.Define(rct3);
  Matrix mx= new Matrix();   //位置
  mx.Tanslate(0,0);
  movie.Frames[1].Add(rct,mx);
  movie.Frames[2].Add(rct1,mx);
  movie.Frames[3].Add(rct2,mx);
  movie.Frames[4].Add(rct3,mx);

  movie.SaveToFile(@"test.swf");
 }


比较遗憾的是,目前没有找到图片压缩的方法~因此输出带图片的swf总是很大~~~
小鱼的淘宝店铺-多多支持哇
小鱼的淘宝店铺-多多支持哇
视频在线上传+队列转换FLV+水印+捉图+修复+获时+转3GP(API语言不限,开视频站必备!)
最近在找有關於 swfdotnet lib 的一些文件,
其實文獻並不多,而且連官網還是義大利文...

這是我在一個網站找到的一篇開放源碼,希望可以跟大家一起討論看看,
swfdotnet lib 到底是怎麼去作用的。

http://www.codeproject.com/KB/graphics/swfdotnet-decompiler.aspx?msg=1889056#xx1889056xx

此文源自這篇。

*

以下程式我自己有下一些註解來幫助自己看懂程式 ( 我還初學.. 或許有些是註解錯誤,希望有大大看到幫忙指教 )

代码 复制 - 运行

/* 
 This sample is an open source library for reading  
 Flash components (SWC files). 
 Copyright (C) 2005 Olivier Carpentier - Adelina foundation 
 see Licence.cs for GPL full text! 

 This library is free software; you can redistribute it and/or 
 modify it under the terms of the GNU General Public 
 License as published by the Free Software Foundation; either 
 version 2.1 of the License, or (at your option) any later version. 

 This library is distributed in the hope that it will be useful, 
 but WITHOUT ANY WARRANTY; without even the implied warranty of 
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 General Public License for more details. 

 You should have received a copy of the GNU General Public 
 License along with this library; if not, write to the Free Software 
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
*/ 
using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.IO; 
using System.Windows.Forms; 
using log4net; 

using SwfDotNet.IO; 
using SwfDotNet.IO.Tags; 
using SwfDotNet.IO.ByteCode; 
using SwfDotNet.IO.ByteCode.Actions; 

namespace SwfDecompiler 
{ 
    public partial class Form1 : Form 
    { 
        private static readonly ILog log = LogManager.GetLogger(typeof(Form1)); 

        public Form1() 
        { 
            InitializeComponent(); 

            string currentPath = Directory.GetCurrentDirectory(); 
            if (currentPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false) 
                currentPath += Path.DirectorySeparatorChar; 
            string output = currentPath + "output\\"; 
            string input = currentPath + "input\\sample.swf"; 
            this.textBoxDir.Text = output; 
            this.textBoxSwf.Text = input; 
        } 

        private void buttonBrowseSwf_Click(object sender, EventArgs e) 
        { 

            DialogResult res = this.openFileDialog1.ShowDialog(); // 開啟檔案資料夾,先將檔案傳到 res 
            if (res == DialogResult.OK) // 視窗確定 OK 
            { 
                if (File.Exists(this.openFileDialog1.FileName)) // 開啟檔案資料夾, 判斷選取的檔案名稱是否存在 
                    this.textBoxSwf.Text = this.openFileDialog1.FileName; // textBoxSwf show 出路徑 
            } 
        } 

        private void buttonBrowseDir_Click(object sender, EventArgs e) 
        { 
            DialogResult res = this.folderBrowserDialog1.ShowDialog();// 開啟瀏覽資料夾,先將檔案傳到 res 
            if (res == DialogResult.OK) // 視窗確定 OK 
            { 
                if (Directory.Exists(this.folderBrowserDialog1.SelectedPath)) // 開啟檔案資料夾, 判斷選取的檔案名稱是否存在 
                    this.textBoxDir.Text = this.folderBrowserDialog1.SelectedPath; // textBoxSwf show 出路徑 
            } 
        } 

        // 判斷是否有檔案匯入與匯出 (視窗) 
        private void TestPath(string fileName, string outputDir)  
        { 
            if (File.Exists(fileName) == false) 
            { 
                MessageBox.Show("Input swf file doesn't exist", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
                return; 
            } 
            else if (Directory.Exists(outputDir) == false) 
            { 
                MessageBox.Show("Output directory doesn't exist", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
                return; 
            } 
        } 

        private void buttonGenerate_Click(object sender, EventArgs e) 
        { 
            // 初始化 資訊的值 
            int numImg = 0; 
            int numSound = 0; 
            int numActionScript = 0; 

            // 宣告 檔案文字 
            string fileName = this.textBoxSwf.Text; 
            string outputDir = this.textBoxDir.Text; 
            TestPath(fileName, outputDir); // 回傳錯誤訊息到 Testpath 

            // ? 
            if (log.IsDebugEnabled)  
                log.Debug("**************** Start to decompile file " + fileName); 

            // 初使化欄位清空 
            this.listViewPix.Items.Clear(); 
            this.listViewSounds.Items.Clear(); 
            this.listViewActionScript.Items.Clear(); 

            SwfReader swfReader = null; // ? 
            try // ? 
            { 
                Cursor.Current = Cursors.WaitCursor; // ? 

                swfReader = new SwfReader(fileName); // Create a swf stream reader 
                Swf swf = swfReader.ReadSwf();   // Read the completed swf file 

                //Read headers infos 讀取 Haders 資訊 
                this.labelSwfVersion.Text = swf.Version.ToString(); // 版本 
                this.labelSwfDim.Text = swf.Header.Width + "x" + swf.Header.Height; // 文件尺寸大小 
                this.labelSwfFps.Text = swf.Header.Fps.ToString(); // Fps 值 
                this.labelSwfFrames.Text = swf.Header.Frames.ToString(); // 總共影格數 
                this.labelSwfSize.Text = swf.Header.FileSize.ToString(); // 檔案大小 
                this.labelSwfSign.Text = swf.Header.Signature; //  

                //Read tags info 讀取 標籤 資訊 
                IEnumerator tagsEnu = swf.Tags.GetEnumerator(); //Browse swf tags list 瀏覽 swf 標籤的清單 
                while (tagsEnu.MoveNext()) 
                { 
                    BaseTag tag = (BaseTag)tagsEnu.Current; 

                    // 取出背景顏色 
                    if (tag is SetBackgroundColorTag) 
                    { 
                        Color bgColor = ((SetBackgroundColorTag)tag).RGB.ToWinColor(); 
                        this.labelSwfBgColor.Text = "R:" + bgColor.R + " G:" + bgColor.G + " B:" + bgColor.B; 
                    } 

                    // 圖片取出 
                    else if (tag is DefineBitsJpeg2Tag) 
                    { 
                        numImg++;  
                        string outfileName = outputDir + GetRandomName() + ".jpg"; // 目錄 + 檔案名稱 Random 破解名稱 
                        ((DefineBitsJpeg2Tag)tag).DecompileToFile(outfileName); // 取出檔案 

                        // ? 
                        string shortName = Path.GetFileName(outfileName); 
                        ListViewItem listViewItem1 = new ListViewItem(new string[] {shortName, "jpg"}, -1); // 建立圖片項目 
                        this.listViewPix.Items.Add(listViewItem1); 
                    } 
                    else if (tag is DefineSoundTag) //Extract a sound file 取出聲音檔: 
                    { 
                        numSound++; 
                        string outfileName = outputDir + GetRandomName(); // 目錄 + 檔案名稱 Random 破解名稱 
                        DefineSoundTag soundTag = (DefineSoundTag)tag; // 聲音導出 

                        // 分類 mp3 或 wav 格式 
                        if (soundTag.SoundFormat == SoundCodec.MP3) 
                            outfileName += ".mp3"; 
                        else 
                            outfileName += ".wav"; 
                        soundTag.DecompileToFile(outfileName); // 導出成文件檔,並以檔名命名 

                        string shortName = Path.GetFileName(outfileName); 
                        ListViewItem listViewItem1 = new ListViewItem(new string[] {shortName, ""}, -1); 
                        this.listViewSounds.Items.Add(listViewItem1); 
                    } 

                    //If tag contains action script... 判斷是否有 action script 
                    if (tag.ActionRecCount != 0)   
     { 
                        StringBuilder sb = new StringBuilder(); // 宣告 sb 為 StringBuilder 
                        IEnumerator enum2 = tag.GetEnumerator(); // Browse tags list 瀏覽 swf 標籤的清單 
      while (enum2.MoveNext()) 
      { 
       Decompiler dc = new Decompiler(swf.Version); 
                            ArrayList actions = dc.Decompile((byte[])enum2.Current); 
       foreach (BaseAction obj in actions) 
       { 
                               sb.AppendLine(obj.ToString()); 
       } 
      } 
                        string outfileName = outputDir + GetRandomName() + ".as"; 

                        StreamWriter writer = new StreamWriter(outfileName); 
                        writer.Write(sb.ToString()); 
                        writer.Close(); 
                        numActionScript++; 

                        string shortName = Path.GetFileName(outfileName); 
                        ListViewItem listViewItem1 = new ListViewItem(new string[] {shortName, ""}, -1); 
                        this.listViewActionScript.Items.Add(listViewItem1); 
     } 
                } 

                Cursor.Current = Cursors.Default; 
                string mssg = "Swf decompiler extracts:\n"; 
                mssg += numImg + " pictures files\n"; 
                mssg += numSound + " sound files\n"; 
                mssg += numActionScript + " action script blocks\n"; 

                MessageBox.Show(mssg, "Decompilation finished", MessageBoxButtons.OK, MessageBoxIcon.Information); 
            } 
            finally 
            { 
                if (swfReader != null) 
                    swfReader.Close();  // Closing stream reader 
                Cursor.Current = Cursors.Default; 
            } 
        } 

        private string GetRandomName() 
        { 
            return RandomPassword.Generate(8, 10); 
        } 

        private void panel1_Paint(object sender, PaintEventArgs e) 
        { 

        } 

    } 
}

其中 有一些問題想請教.. 因為看不懂程式的意思..

代码 复制 - 运行

//If tag contains action script... 判斷是否有 action script 
                    if (tag.ActionRecCount != 0)   
     { 
                        StringBuilder sb = new StringBuilder(); // 宣告 sb 為 StringBuilder 
                        IEnumerator enum2 = tag.GetEnumerator(); // Browse tags list 瀏覽 swf 標籤的清單 
      while (enum2.MoveNext()) 
      { 
       Decompiler dc = new Decompiler(swf.Version); 
                            ArrayList actions = dc.Decompile((byte[])enum2.Current); 
       foreach (BaseAction obj in actions) 
       { 
                               sb.AppendLine(obj.ToString()); 
       } 
      } 
                        string outfileName = outputDir + GetRandomName() + ".as"; 

                        StreamWriter writer = new StreamWriter(outfileName); 
                        writer.Write(sb.ToString()); 
                        writer.Close(); 
                        numActionScript++; 

                        string shortName = Path.GetFileName(outfileName); 
                        ListViewItem listViewItem1 = new ListViewItem(new string[] {shortName, ""}, -1); 
                        this.listViewActionScript.Items.Add(listViewItem1); 
     } 
                }

到底是什麼作用呀.. 我刪掉後,他似乎也沒差一樣....↓

代码 复制 - 运行

Cursor.Current = Cursors.Default;  

{shortName, "jpg"}, -1); 的-1 用途在哪呀?↓

代码 复制 - 运行

string shortName = Path.GetFileName(outfileName); 
                        ListViewItem listViewItem1 = new ListViewItem(new string[] {shortName, "jpg"}, -1); // 建立圖片項目 
                        this.listViewPix.Items.Add(listViewItem1); 


以上問題,希望可以跟高手們跟進!!!! 感謝
讨论地址:http://www.blueshop.com.tw/board/show.asp?subcde=BRD201002271359061PV

RE:
有這麼難理解嗎? @.@a

這支程式的主要目的是拆解 swf 檔,工作行程可能需要一段時間,而原作者選擇在
程式開始執行拆解的時候,將游標顯示為等待游標 ,程式碼 116 行:

Cursor.Current = Cursors.WaitCursor;

一方面告知工作正在處理中,一方面也讓使用者無法做任何動作,參考 Cursor.Current
屬性說明文件裡的備註小節:


如果您設定 Current 屬性,就會變更目前顯示的游標。如此,應用程式就不一定會
繼續接聽滑鼠事件 (Mouse Event)。若要通知應用程式不應該在長時間執行的作業期
間回應滑鼠事件,請使用 UseWaitCursor 屬性。不過,在大部分情況下,最好是使
用背景執行緒來管理長時間執行的作業,並讓使用者能夠存取使用者介面。


直到拆解工作結束,才又將游標變更回預設游標,程式碼 199、211 行:

Cursor.Current = Cursors.Default;
本帖最后由 张小鱼 于 2012-02-07 15:13 编辑
小鱼的淘宝店铺-多多支持哇

提取 FLV 中的音频

视频在线上传+队列转换FLV+水印+捉图+修复+获时+转3GP(API语言不限,开视频站必备!)
http://zhq.ahau.edu.cn/blog/article/464.htm

好久没有写东西了, 八月份写过一篇<提取 SWF 中的音频>, 这篇写 FLV 中提取音频, 算是上篇的姊妹篇. 本篇在一个多月之前就开了头, 并且代码也写好了, 每次想完成本文都不了了之了.  哎, 变懒了.
这次使用的 FLV 操作组件还是 SwfDotNet, 不过此组件对 FLV 操作部分没有开发完毕, 使用的时候完善了一部分代码, 并修改了一部分错误, 最后总算提取音频部分成功.
修改 SwfDotNet 类库的时候参考了Adobe 官方的 <Video File Format Specification Version 9>. 这个格式文档不但包括 FLV 格式说明, 还包括 F4V 格式说明.
FLV 文件字节编码格式为 BigEndianUnicode , SwfDotNet 内已经把处理方法给封装好了, 但不知道使用.Net框架的附带默认编码处理方式是否可以, SwfDotNet 作者把框架内好多附带方法都重新实现了一边, 这个不清楚为啥.
FLV 文件结构主要由两部分组成, Header 部分与 TAG 组部分. Header 的长度和结构是固定的, 前三个字节为固定的FLV标志, 其他的表示当前FLV文件是否有音频或视频部分, 还有一些空白的字节, 总共为9个字节. TAG 组为由三类 FLVTAG 和UI32类型的PreviousTagSize 交替组成, PreviousTagSize 标识其前的FLVTAG的大小, FLVTAG的基本结构为:

字段名称类型说明
TagTypeUI8
本TAG的类型. 可取值:
    8: audio
    9: video
    18: script data
    其他的: 保留
DataSizeUI24Data字段的数据长度
TimestampUI24无用?
TimestampExtendedUI8对上面的字段扩展之用
StreamIDUI24总是 0
Data
    If TagType = 8
    AUDIODATA
    If TagType = 9
    VIDEODATA
    If TagType = 18
    SCRIPTDATAOBJECT
TAG 数据字段, 主要的数据就在这个里面. 本字段的数据类型取决与TagType内的值

实际上只要关心三个字段:TagType/DataSize/Data. 从TagType来判断Data字段的类型, Data字段的大小从DataSize字段来确定. 对于音频格式来说只要处理TagType为8的Data字段数据, 其他的TagType按着DataSize的大小偏移, 忽略掉.
三类 FLVTAG 实际上就是上面结构中的 TagType 值:
    8  AUDIO TAG 音频TAG (音频结构的TAG, 也是本文处理时所关心的. 本TAG类似与 SWF中的 DefineSound TAG)
    9  VIDEO TAG 视频TAG (视频结构的TAG, 类似于SWF中的VideoFrame TAG. 此TAG实际上才是FLV的视频.)
    18  SCRIPTDATAOBJECT TAG 脚本数据对象TAG(保存FLV部分元数据之用)

AUDIO TAG的Data结构为:

字段称类型说明
SoundFormatUB[4]

0 = Linear PCM, platform endian
1 = ADPCM
2 = MP3
3 = Linear PCM, little endian
4 = Nellymoser 16-kHz mono
5 = Nellymoser 8-kHz mono
6 = Nellymoser
7 = G.711 A-law logarithmic PCM
8 = G.711 mu-law logarithmic PCM
9 = reserved
10 = AAC
14 = MP3 8-Khz
15 = Device-specific sound

SoundData 字段内音频的存储格式
格式7, 8, 14, 15 保留专用
格式10 (AAC) 只有在 Flash Player 9.0.115.0 及以上版本提供.
这里只关心 MP3 格式的, 因为其他编号的还不确定咋样处理.
SoundRateUB[2]
0 = 5.5-kHz
1 = 11-kHz
2 = 22-kHz
3 = 44-kHz

取样率 对AAC格式: 总为 3
SoundSize
UB[1]
0 = snd8Bit 8位
1 = snd16Bit 16位

每个取样的大小
对AAC格式: 总为 1
实际本字段为一个逻辑类型字段
SoundType
UB[1]
0 = sndMono 单声道
1 = sndStereo 立体声

标示是 立体或单声道的声音
对于Nellymoser格式: 总为 0
对于AAC格式: 总为 1
本字段也可以理解为逻辑类型字段
SoundDataUI8[sound data长度]
如果 SoundFormat 字段为 10
本数据为 AACAUDIODATA 类型的音频数据(本文忽略处理)
否则为实际的音频数据
对于MP3格式的音频数据直接将本字段的数据当成MP3数据来处理

SoundFormat/SoundRate/SoundSize/SoundType 加起来正好一个字节, 使得 SoundData 字段的数据大小为 FLVTAG 内 DataSize 字段的值减1.
前面已经指出"每一个FLVTAG 字段之后有一个UI32类型的PreviousTagSize" 其内的值正好为其前的FLVTAG长度, 这个部分应该校验之用.
从上面来算如果直接提取FLV的时候需要以下几步:
    偏移9个字节
    空一个3字节长度的UI32类型的PreviousTagSize0
    读一个字节的UI8类型的TagType字段, 如果本字段为8处理音频数据, 其他的部分, 按下一步获得的DataSize值偏移制定的字节
    再读3个字节的UI24类型的DataSize字段, 确定SoundData部分的数据大小
    对于AUDIODATA 读取4Bit 判断是否为MP3类型的数据, 如果非MP3格式的也按着DataSize大小偏移忽略掉
    偏移4位, 开始获取SoundData部分数据. SoundData的大小从第三步获得的DataSize来确定大小, 应该为 DataSize-1
    偏移3个字节长度的UI32类型的PreviousTagSize部分
    重复第三步

经过上面操作讲获得的全部的SoundData数据合并输出到一个MP3扩展名的文件. 不过本篇文章中没有使用上面的方法, 计划在下一篇中贴出实现代码.
下面是使用SwfDotNet 的实现代码:

代码 复制 - 运行

/// <summary> 
/// 输出FLV音频部分 
/// </summary> 
private void FlvOutSound() 
{ 
    string fileName = Path.GetFileName(flvFile); 
    string outFileFileName = string.Format("{0}.{1}", fileName, "mp3"); 
    //读取FLV文件 
    FlvReader flvReader = new FlvReader(flvFile, true); 
    Flv flv = flvReader.ReadFlv(); 

    using (FileStream stream = new FileStream(Path.Combine(outPath, outFileFileName), FileMode.OpenOrCreate, FileAccess.Write)) 
    { 
        foreach (FlvBaseTag tag in flv.Tags) 
        { 
            //只处理AudioTAG 
            if (tag is FlvAudioTag) 
            { 
                FlvAudioTag audio = tag as FlvAudioTag; 
                //输出到文件 
                stream.Write(audio.SoundData, 0, audio.SoundData.Length); 
            } 
        } 
    } 
} 
/// <summary> 
/// 输入的FLV文件 
/// </summary> 
string flvFile = null; 
/// <summary> 
/// 输出的MP3文件目录 
/// </summary> 
string outPath = null;SwfDotNet 类库 FlvReader.cs 内的处理错误部分纠正 

/// <summary> 
/// Reads the tag. 
/// </summary> 
/// <returns></returns> 
private FlvBaseTag ReadTag() 
{ 
    FlvBaseTag resTag = null; 
    //不读取, 只测试当前的Tag 类型 
    byte tagType = br.PeekByte(); 

    switch (tagType) 
    { 
        case (byte) FlvTagCodeEnum.Audio: 
            resTag = new FlvAudioTag(); 
            break; 
        case (byte)FlvTagCodeEnum.Video: //这个处理部分和FlvScriptTag内的处理一致, 只是简单的偏移 
            resTag = new FlvVideoTag(); 
            break; 
        case (byte)FlvTagCodeEnum.Script: 
        default: 
            resTag = new FlvScriptTag(); 
            break; 
    } 

    resTag.ReadData(version, br); 
    br.ReadUInt32(); 

    return resTag; 
}

主要的代码就这么点, 好像有点头重脚轻. 不过功能是全部实现了.  全部完成了想说明一下FLV中提取音频的用处. 因为自己喜欢听相声, 在几个播客网站下载了好多的视频, 但大部分是FLV类型的,  FLV的视频部分视乎是多余, 插上耳机听就可以了, 也不常看视频部分, 所以就有了本文的想法, 不过总算难度不大.
下一篇计划写关于"摆脱 SwfDotNet 类库提取音频"的实现代码部分.
本文主要参考: <Video File Format Specification Version 9>.
这里是代码. 下载地址:
http://st780206.iteye.com/blog/665555
本帖最后由 张小鱼 于 2012-02-07 15:16 编辑
小鱼的淘宝店铺-多多支持哇
视频在线上传+队列转换FLV+水印+捉图+修复+获时+转3GP(API语言不限,开视频站必备!)
http://www.c-sharpcorner.com/UploadFile/krishnasarala/convert-images-to-swf-format-using-C-Sharp/
小鱼的淘宝店铺-多多支持哇
视频在线上传+队列转换FLV+水印+捉图+修复+获时+转3GP(API语言不限,开视频站必备!)
SwfDotNet is an open source library to read and write binary Swf files in C# or VB.net.This library has been writted by Olivier CARPENTIER for the Adelina foundation.This library is realeased under the GPL license, please read License.txt file.Olivier CARPENTIERFor more informations:Web site:http://sourceforge.net/projects/swfdotnet/

https://github.com/lvaleriu/SwfDecompiler/tree/master/Plugins/swfdotnet-1.0

主:https://github.com/lvaleriu/SwfDecompiler






见:http://fish.baobao6.com/WebLanguage/thread-1741-1-1.aspx
小鱼的淘宝店铺-多多支持哇