1. 程式人生 > >C#網易雲音樂中需付費歌曲的下載助手。

C#網易雲音樂中需付費歌曲的下載助手。

           網易雲音樂要收費了,部分歌曲只能聽不能下載,還是很遺憾的。閒來無事,寫了個收費歌曲的下載助手。

下載連結:連結:http://pan.baidu.com/s/1ge5stgB 密碼:f9qo

使用方法:

1、安裝.net framework 4.0 (若沒裝的話,下載地址:https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=17718)

2、安裝網易雲音樂客戶端

3、開啟“下載助手”,設定好下載儲存地址,如下圖:


4、選中所需下載的音樂,點右鍵,點複製連結,如下圖:


5、下載就開始了。。。。。就這麼簡單。。。。。

(只要複製歌曲連結,就能自動新增到下載助手裡面喲,然後自動下載。)


6、可以一個勁複製很多連結(重複4操作)。

7、退出軟體,點“”沒用的。。會退到後臺。必須在狀態列找到以下圖示,點右鍵,點退出

              
8、若覺得對您有幫助,可以發個微信紅包打賞哦


(微訊號:li1239019842)

缺點:

下載的音樂不是高品質的。。。

---------------------------------------------------分割線---------------------------------------------------------

原理:通過網易雲音樂客戶端複製的音樂連結中獲取音樂ID(紅色),

“http://music.163.com/#/m/song?id=27804029&userid=98810162”

將歌曲id替換以下連結中“XXXXXX”
http://music.163.com/api/song/detail/?id=XXXXXX&ids=%5BXXXXXX%5D&csrf_token=

網址輸入瀏覽器中返回json語句,其中“mp3Url”即為歌曲連結,如下:
http://m2.music.126.net/MEYfrcH-XivohQ01yOsoCw==/3288639278734103.mp3

這就是音樂的下載地址。。。。

-------------------------------------------------原始碼--------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;

namespace NeteaseCouldMusicDownload
{
    public partial class Form1 : Form
    {
        [System.Runtime.InteropServices.DllImport("user32")]
        private static extern IntPtr SetClipboardViewer(IntPtr hwnd);
        [System.Runtime.InteropServices.DllImport("user32")]
        private static extern IntPtr ChangeClipboardChain(IntPtr hwnd, IntPtr hWndNext);
        [System.Runtime.InteropServices.DllImport("user32")]
        private static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

        const int WM_DRAWCLIPBOARD = 0x308;
        const int WM_CHANGECBCHAIN = 0x30D;
        IntPtr NextClipHwnd;

        private static StreamWriter sw;

        int id;
        int finished;
        Thread t;
        public Form1()
        {
            InitializeComponent();
            id = 0;
        }

        private void btnSelectPath_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbDialog = new FolderBrowserDialog();
            fbDialog.Description = "請選擇檔案儲存路徑";
            if(fbDialog.ShowDialog() == DialogResult.OK)
            {
                txtPath.Text = fbDialog.SelectedPath;
                string iniPathName = Environment.CurrentDirectory + "\\Default.ini";
                OperateIniFile.WriteIniData("Dictionary", "key", txtPath.Text, iniPathName);
            }
        }
        private void AddDownload(string url)
        {
            url = TransfromUrl(url);
            if (string.IsNullOrEmpty(url))
            {
                return;
            }
            if (url != "error")
            {
                Song song = DownloadHelper.GetMusicUrl(DownloadHelper.GetWebContent(url));
                if (song == null)
                {
                    return;
                }
                if (File.Exists(txtPath + "\\" + song.songName + "." + song.extension))
                {
                    File.Delete(txtPath + "\\" + song.songName + "." + song.extension);
                }
                DataGridViewRow dr = new DataGridViewRow();
                dr.CreateCells(dataGridView1);
                dr.Cells[0].Value = id + 1;
                dr.Cells[1].Value = song.songName + "." + song.extension;
                dr.Cells[2].Value = song.singer;
                dr.Cells[3].Value = (Convert.ToDouble(song.songSize) / 1024 / 1024).ToString("0.00M");
                dr.Cells[4].Value = "0%";
                dr.Cells[5].Value = song.songUrl;
                dataGridView1.Rows.Add(dr);
                txtUrl.Text = "";
                id++;
                t.Resume(); //恢復執行緒
            }
        }
        private void btnDownload_Click(object sender, EventArgs e)
        {
            string url = TransfromUrl(txtUrl.Text);
            if (string.IsNullOrEmpty(url))
            {
                MessageBox.Show("請輸入歌曲連結!");
                return;
            }
            if (url != "error")
            {
                Song song = DownloadHelper.GetMusicUrl(DownloadHelper.GetWebContent(url));
                if (song == null)
                {
                    MessageBox.Show("找不到歌曲!");
                    return;
                }
                if (File.Exists(txtPath + "\\" + song.songName + "." + song.extension))
                {
                    File.Delete(txtPath + "\\" + song.songName + "." + song.extension);
                }
                DataGridViewRow dr = new DataGridViewRow();
                dr.CreateCells(dataGridView1);
                dr.Cells[0].Value = id+1;
                dr.Cells[1].Value = song.songName+"."+song.extension;
                dr.Cells[2].Value = song.singer;
                dr.Cells[3].Value = (Convert.ToDouble(song.songSize)/1024/1024).ToString("0.00M");
                dr.Cells[4].Value = "0%";
                dr.Cells[5].Value = song.songUrl;
                dataGridView1.Rows.Add(dr);
                txtUrl.Text = "";
                Thread.Sleep(100);
                id++;
                t.Resume(); //恢復執行緒
            }
            else
            {
                MessageBox.Show("歌曲連結錯誤!");
            }
        }
        private string TransfromUrl(string url)
        {
            if (string.IsNullOrEmpty(url))
            {
                return "";
            }

            string[] tmp = url.Split(new char[]{'?','=','&'});
            if (tmp.Length>1 && tmp[1] == "id")
            {
                return "http://music.163.com/api/song/detail/?id=" + tmp[2] + "&ids=%5B" + tmp[2] + "%5D&csrf_token=";
            }
            else
                return "error";
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            NextClipHwnd = SetClipboardViewer(this.Handle);
            string iniPathName = Environment.CurrentDirectory + "\\Default.ini";
            OperateIniFile.Checkini(iniPathName);
            string songPath = OperateIniFile.ReadIniData("Dictionary", "key", "Empty", iniPathName);
            if (System.IO.Directory.Exists(songPath))
            {
                txtPath.Text = songPath;
            }
            else
            {
                txtPath.Text = Environment.CurrentDirectory;
                OperateIniFile.WriteIniData("Dictionary", "key", txtPath.Text, iniPathName);
            }
            t = new Thread(new ThreadStart(DownloadProc));
            id = 0;        //新增下載的數目
            finished = 0;  //已下載數
            t.Start();     //啟動下載執行緒
        }

        private void DownloadProc()
        {
            while (true)
            {
                if (finished < id)
                {
                    DownloadHelper.DownloadFile(ref dataGridView1, txtPath.Text, finished, null);
                    finished++;
                }
                else
                {
                    Thread.Sleep(1000);
                    t.Suspend(); //掛起執行緒
                }
            }
        }

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            switch (m.Msg)
            {
                case WM_DRAWCLIPBOARD:
                    //將WM_DRAWCLIPBOARD訊息傳遞到下一個觀察鏈中的視窗
                    SendMessage(NextClipHwnd, m.Msg, m.WParam, m.LParam);
                    IDataObject iData = Clipboard.GetDataObject();
                    //檢測文字
                    if (iData.GetDataPresent(DataFormats.Text) | iData.GetDataPresent(DataFormats.OemText))
                    {
                        if (iData != null && System.IO.Directory.Exists(txtPath.Text))
                        { 
                            string url = (String)iData.GetData(DataFormats.Text);
                            AddDownload(url);
                        }
                    }
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }

        private void ToolMenuShow_Click(object sender, EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
            this.Activate();   //啟用窗體給予焦點
        }

        private void ToolMenuClose_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("確定要退出程式?", "安全提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
            if (dr == DialogResult.Yes)
            {

                notifyIcon1.Visible = false;
                this.Close();
                this.Dispose();
                t.Resume();
                t.Abort();
                
                Application.Exit();
            }
        }

        private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.Visible = true;
                this.WindowState = FormWindowState.Normal;
                this.notifyIcon1.Visible = true;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;  //取消關閉操作,表現為不關閉窗體
                this.Hide();     //隱藏窗體
            }
        }

    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Windows.Forms;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Runtime.InteropServices;

namespace NeteaseCouldMusicDownload
{
    class Song
    {
        public string songUrl { get; set; }
        public string songName { get; set; }
        public string singer { get; set; }
        public string songSize { get; set; }
        public string extension { get; set; }
    }
    class DownloadHelper
    {
        /// <summary>
        /// 獲得Json字串
        /// </summary>
        /// <param name="Url">網址</param>
        /// <returns></returns>
        public static string GetWebContent(string Url)
        {
            string strResult = "";
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
                //宣告一個HttpWebRequest請求
                request.Timeout = 30000;
                //設定連線超時時間
                request.Headers.Set("Pragma", "no-cache");
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream streamReceive = response.GetResponseStream();
                StreamReader streamReader = new StreamReader(streamReceive, Encoding.GetEncoding("UTF-8"));
                strResult = streamReader.ReadToEnd();
            }
            catch(Exception e)
            {
                MessageBox.Show(e.ToString()+":"+e.Message);
            }
            return strResult;
        }
        /// <summary>
        /// 解析Json語句,得到音樂資訊
        /// </summary>
        /// <param name="jsonStr"></param>
        /// <returns></returns>
        public static Song GetMusicUrl(string jsonStr)
        {
            Song song = new Song();
            JObject jsonobj = JObject.Parse(jsonStr);
            JArray jar = JArray.Parse(jsonobj["songs"].ToString());
            if (jar.Count == 0)
                return null;
            JObject songobj = JObject.Parse(jar[0].ToString());
            song.songUrl =  songobj["mp3Url"].ToString();
            song.songName = songobj["name"].ToString();

            song.singer = JObject.Parse(JArray.Parse(songobj["artists"].ToString())[0].ToString())["name"].ToString();
            song.songSize = JObject.Parse(songobj["bMusic"].ToString())["size"].ToString();
            song.extension = JObject.Parse(songobj["bMusic"].ToString())["extension"].ToString();

            return song;
        }
        /// <summary>
        /// 通過url下載檔案
        /// </summary>
        /// <param name="URL">網址連結</param>
        /// <param name="filename">儲存路徑</param>
        /// <param name="prog"></param>
        /// <param name="label1"></param>
        public static void DownloadFile(ref DataGridView grid,string path,int row,ProgressBar prog)
        {
            string URL = grid.Rows[row].Cells[5].Value.ToString();
            string filename = path + "\\" + grid.Rows[row].Cells[1].Value.ToString();
            float percent = 0;
            try
            {
                System.Net.HttpWebRequest Myrq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(URL);
                System.Net.HttpWebResponse myrp = (System.Net.HttpWebResponse)Myrq.GetResponse();
                long totalBytes = myrp.ContentLength;
                if (prog != null)
                {
                    prog.Maximum = (int)totalBytes;
                }
                System.IO.Stream st = myrp.GetResponseStream();
                System.IO.Stream so = new System.IO.FileStream(filename, System.IO.FileMode.Create);
                long totalDownloadedByte = 0;
                byte[] by = new byte[102400];
                int osize = st.Read(by, 0, (int)by.Length);
                while (osize > 0)
                {
                    totalDownloadedByte = osize + totalDownloadedByte;
                    System.Windows.Forms.Application.DoEvents();
                    so.Write(by, 0, osize);
                    if (prog != null)
                    {
                        prog.Value = (int)totalDownloadedByte;
                    }
                    osize = st.Read(by, 0, (int)by.Length);

                    percent = (float)totalDownloadedByte / (float)totalBytes * 100;
                    grid.Rows[row].Cells[4].Value = percent.ToString("0.0") + "%";
                    System.Windows.Forms.Application.DoEvents(); //必須加註這句程式碼,否則label1將因為迴圈執行太快而來不及顯示資訊
                }
                so.Close();
                st.Close();
            }
            catch (System.Exception)
            {
                throw;
            }
        }
    }
    public class OperateIniFile
    {
        #region API函式宣告

        [DllImport("kernel32")]//返回0表示失敗,非0為成功
        private static extern long WritePrivateProfileString(string section, string key,
            string val, string filePath);

        [DllImport("kernel32")]//返回取得字串緩衝區的長度
        private static extern long GetPrivateProfileString(string section, string key,
            string def, StringBuilder retVal, int size, string filePath);


        #endregion

        #region 讀Ini檔案

        public static string ReadIniData(string Section, string Key, string NoText, string iniFilePath)
        {
            if (File.Exists(iniFilePath))
            {
                StringBuilder temp = new StringBuilder(1024);
                GetPrivateProfileString(Section, Key, NoText, temp, 1024, iniFilePath);
                return temp.ToString();
            }
            else
            {
                return String.Empty;
            }
        }

        #endregion

        #region 寫Ini檔案

        public static bool WriteIniData(string Section, string Key, string Value, string iniFilePath)
        {
            if (File.Exists(iniFilePath))
            {
                long OpStation = WritePrivateProfileString(Section, Key, Value, iniFilePath);
                if (OpStation == 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            else
            {
                return false;
            }
        }

        #endregion

        public static bool Checkini(string pathName)
        {
            if (!File.Exists(pathName))
            {
               File.Create(pathName).Close();
            }
            return true;
        }
    }
}