protected override void WorkerDoWork(DoWorkEventArgs e)
        {
            if (_mode == ConvertingMode.File)
            {
                try
                {
                    using (var logger = OperationLogger.Create(OperationLogger.FFmpegDLogFile))
                    {
                        FFmpeg.Convert(this.Input, this.Output, this.ReportProgress, _cts.Token, logger);

                        // Crop if not operation wasn't canceled and _start has a valid value
                        if (!this.CancellationPending && _start != TimeSpan.MinValue)
                        {
                            // Crop to end of file, unless _end has a valid value
                            if (_end == TimeSpan.MinValue)
                            {
                                FFmpeg.Crop(this.Output, this.Output, _start, this.ReportProgress, _cts.Token, logger);
                            }
                            else
                            {
                                FFmpeg.Crop(this.Output, this.Output, _start, _end, this.ReportProgress, _cts.Token, logger);
                            }
                        }
                    }

                    // Reset variables
                    _start = _end = TimeSpan.MinValue;
                }
                catch (Exception ex)
                {
                    Common.SaveException(ex);
                    Helper.DeleteFiles(this.Output);
                    e.Result = OperationStatus.Failed;
                }
            }
            else
            {
                using (var logger = OperationLogger.Create(OperationLogger.FFmpegDLogFile))
                {
                    foreach (string input in Directory.GetFiles(this.Input, _searchPattern))
                    {
                        if (this.CancellationPending)
                        {
                            break;
                        }

                        _count++;
                        try
                        {
                            string output = string.Format("{0}\\{1}.mp3",
                                                          this.Output,
                                                          Path.GetFileNameWithoutExtension(input));

                            this.ReportProgress(UpdateProperties, new Dictionary <string, object>()
                            {
                                { nameof(Operation.Title), Path.GetFileName(input) },
                                { nameof(Operation.Duration), (int)FFmpeg.GetDuration(input).Value.TotalSeconds },
                                { nameof(Operation.FileSize), Helper.GetFileSize(input) }
                            });

                            _currentOutput = output;
                            FFmpeg.Convert(input, output, this.ReportProgress, _cts.Token, logger);
                            _currentOutput = null;

                            this.ProcessedFiles.Add(output);
                        }
                        catch (Exception ex)
                        {
                            _failures++;
                            Common.SaveException(ex);
                            Helper.DeleteFiles(_currentOutput);
                            continue;
                        }
                    }
                }
            }

            // Set operation result
            e.Result = this.CancellationPending ? OperationStatus.Canceled : OperationStatus.Success;
        }
Пример #2
0
        //========== CONVERTING ==========
        #region Converting

        /**<summary>Converts the specified wave input file and writes it to the output file.</summary>*/
        public static bool Convert(string inputFile, string outputFile, bool changeExtension)
        {
            if (changeExtension)
            {
                outputFile = Path.ChangeExtension(outputFile, ".xnb");
            }

            string ext    = Path.GetExtension(inputFile).ToLower();
            bool   isTemp = false;

            if (ext != ".wav")
            {
                isTemp = true;
                string tempOut = Path.Combine(TempConverting, Random.Next().ToString() + ".wav");
                if (!FFmpeg.Convert(inputFile, tempOut))
                {
                    throw new WavException("Failed to convert to wav format.");
                }
                inputFile = tempOut;
            }

            ushort wFormatTag;
            ushort nChannels;
            uint   nSamplesPerSec;
            uint   nAvgBytesPerSec;
            ushort nBlockAlign;
            ushort wBitsPerSample;

            int dataChunkSize;

            byte[] waveData;

            using (FileStream inputStream = new FileStream(inputFile, FileMode.Open)) {
                using (BinaryReader reader = new BinaryReader(inputStream)) {
                    string format = new string(reader.ReadChars(4));
                    if (format != "RIFF")
                    {
                        throw new WavException("Invalid file format: " + format + ".");
                    }

                    uint fileLength = reader.ReadUInt32();
                    if (fileLength != inputStream.Length - 8)
                    {
                        throw new WavException("File length mismatch: " + fileLength + " - should be " + inputStream.Length + ".");
                    }

                    format = new string(reader.ReadChars(4));
                    if (format != "WAVE")
                    {
                        throw new WavException("No WAVE tag. (" + format + ")");
                    }

                    format = new string(reader.ReadChars(4));
                    if (format != "fmt ")
                    {
                        throw new WavException("No fmt tag. (" + format + ")");
                    }

                    int chunkSize = reader.ReadInt32();
                    if (chunkSize < 16)
                    {
                        throw new WavException("Incorrect format length.");
                    }
                    chunkSize += (int)inputStream.Position;

                    if ((wFormatTag = reader.ReadUInt16()) != 1)
                    {
                        throw new Exception("Unimplemented wav codec (must be PCM).");
                    }

                    nChannels = reader.ReadUInt16();

                    nSamplesPerSec = reader.ReadUInt32();

                    nAvgBytesPerSec = reader.ReadUInt32();

                    nBlockAlign = reader.ReadUInt16();

                    wBitsPerSample = reader.ReadUInt16();

                    if (nAvgBytesPerSec != (nSamplesPerSec * nChannels * (wBitsPerSample / 8)))
                    {
                        throw new WavException("Average bytes per second number incorrect.");
                    }
                    if (nBlockAlign != (nChannels * (wBitsPerSample / 8)))
                    {
                        throw new WavException("Block align number incorrect.");
                    }

                    inputStream.Position = chunkSize;

                    format        = new string(reader.ReadChars(4));
                    dataChunkSize = reader.ReadInt32();
                    while (format != "data")
                    {
                        inputStream.Position += dataChunkSize;
                        format        = new string(reader.ReadChars(4));
                        dataChunkSize = reader.ReadInt32();
                        if (dataChunkSize < 0 || dataChunkSize + (int)inputStream.Position > (int)inputStream.Length)
                        {
                            break;
                        }
                    }
                    if (format != "data")
                    {
                        throw new WavException("No data tag.");
                    }

                    waveData = reader.ReadBytes(dataChunkSize);
                }
            }

            using (FileStream outputStream = new FileStream(outputFile, FileMode.OpenOrCreate)) {
                using (BinaryWriter writer = new BinaryWriter(outputStream)) {
                    outputStream.SetLength(0);

                    writer.Write(Encoding.UTF8.GetBytes("XNB")); // Format identifier
                    writer.Write(Encoding.UTF8.GetBytes("w"));   // TargetPlatform Windows
                    writer.Write((byte)5);                       // XNB format version

                    writer.Write((byte)0);                       // Flag bits:
                    // File Size TODO
                    writer.Write(dataChunkSize + 105);           //??  61?
                    writer.Write7BitEncodedInt(1);               // Type Reader count

                    writer.Write(SoundEffectType);               // String reader name

                    writer.Write(0);                             // reader version number
                    writer.Write((byte)0);                       // shared Resource Count
                    writer.Write((byte)1);                       // Object Primary asset data....?

                    writer.Write(18);                            // Format size
                    // Format
                    writer.Write((ushort)wFormatTag);            // ushort wFormatTag;
                    writer.Write((ushort)nChannels);             // ushort nChannels;
                    writer.Write((uint)nSamplesPerSec);          // uint nSamplesPerSec;
                    writer.Write((uint)nAvgBytesPerSec);         // uint nAvgBytesPerSec;
                    writer.Write((ushort)nBlockAlign);           // ushort nBlockAlign;
                    writer.Write((ushort)wBitsPerSample);        // ushort wBitsPerSample;
                    writer.Write((ushort)0);                     // ushort cbSize;

                    writer.Write(dataChunkSize);                 // Uint32 Data Size
                    writer.Write(waveData);                      // Byte[data size] data

                    writer.Write(0);                             // int32 loop start
                    writer.Write(dataChunkSize / nBlockAlign);   // int32 loop length

                    // int32 duration
                    writer.Write((int)(1000 * dataChunkSize / (nChannels * wBitsPerSample * nSamplesPerSec / 8)));
                }
            }

            if (isTemp)
            {
                File.Delete(inputFile);
            }
            return(true);
        }