I'm creating an video downloading app in C# and Universal Windows Platform. App downloads movies in three different file sets depending on the source:
- .ts audio & video file
- .mp4 only video file and .webm only audio file
- .mp4 audio & video file The video lenghts, on which I tested the app, range from a few seconds to several hours. Video qualities are standard YouTube qualities.
The next step is video editing. User can specify start and end trimming timestamp. Video can be saved in three different modes:
- Audio & Video
- Only audio
- Only video
This is where the problem begins.
I can't use FFmpeg as executable, because UWP framework doesn't allow to run external app.
So I tried to use Windows.Media.Editing library. It works fine with all .mp4 audio & video files and some .ts files (but only with short videos up to an hour). Other cases throws two types of exceptions:
- System.Exception HResult=0xC00DA7FC Message=Stream is not in a state to handle the request. Stream is not in a state to handle the request. Source=System.Private.CoreLib
- System.Exception HResult=0xC00D6D60 Message=A valid type has not been set for this stream or a stream that it depends on. (Exception from HRESULT: 0xC00D6D60) Source=System.Private.CoreLib
I wrote a separate question about it: Exception when rendering a video in UWP . Here is also a link to an example (In comments with sample videos, which causes an error. Link to github repository.) that downloads and tries to convert the .ts file to the .mp4 file.
So I decided to try the most complicated solution. I created a C++ DLL project and set build output destination to the new folder in the main app project folder (and set this folder to copy to build output directory). I installed an ffmpeg libraries by vcpkg and imported them in C++ project. Here is the .cpp file:
#include "pch.h"
#include "mux.h"
extern "C" {
#include "libavformat/avformat.h"
}
int test() {
av_register_all();
return 0;
}
Here is the header:
#pragma once
#ifdef FFMPEGLIB_EXPORTS
#define FFMPEGLIB_API __declspec(dllexport)
#else
#define FFMPEGLIB_API __declspec(dllimport)
#endif
extern "C" FFMPEGLIB_API int test();
And here is the C# class where is imported C++ function:
class FFmpeg
{
[DllImport(@"FFmpeg\FFmpegLib.dll")] private static extern int test();
public static void Test()
{
test();
}
}
But calling an Test() void throws an error: System.DllNotFoundException: 'Unable to load DLL 'FFmpeg\FFmpegLib.dll' or one of its dependencies: The specified module could not be found. (Exception from HRESULT: 0x8007007E)'
There are also ffmpeg libraries (avcodec-58.dll, avformat-58.dll, avutil-56.dll, swresample-3.dll) in FFmpeg folder. I also tried to import avformat-58.dll directly in C# (main app project) and call av_register_all() function, but it throws the same exception. I also checked if I could include "libavformat/avformat.h" in C++ UWP app, but it shows error "cannot open source file "libavformat/avformat.h"". I guess that C libraries are incompatible with UWP, but I'm not sure.
I have no more ideas. If it is not possible to use the methods I have mentioned, my question is Are there any other ways to process videos in UWP app?