.net에서 FFmpeg를 사용하십니까?
그래서 나는 그것이 상당히 큰 도전이라는 것을 알고 있지만 FFmpeg 라이브러리를 사용하여 C #으로 기본 영화 플레이어 / 변환기를 작성하고 싶습니다. 그러나 극복해야 할 첫 번째 장애물은 FFmpeg 라이브러리를 c #으로 래핑하는 것입니다. ffmpeg를 다운로드했지만 Windows에서 컴파일 할 수 없어서 미리 컴파일 된 버전을 다운로드했습니다. 좋습니다. 그런 다음 C # 래퍼를 찾기 시작했습니다.
나는 주위를 둘러 보았고 SharpFFmpeg ( http://sourceforge.net/projects/sharpffmpeg/ ) 및 ffmpeg-sharp ( http://code.google.com/p/ffmpeg-sharp/ ) 와 같은 몇 가지 래퍼를 발견했습니다 . 우선 LGPL과 SharpFFmpeg가 GPL이므로 ffmpeg-sharp를 사용하고 싶었습니다. 그러나 꽤 많은 컴파일 오류가있었습니다. 모노 컴파일러 용으로 작성된 것으로 밝혀졌지만 모노로 컴파일을 시도했지만 방법을 알 수 없었습니다. 그런 다음 수동으로 컴파일러 오류를 수정하기 시작했지만 몇 가지 무서운 오류를 발견하고 그대로 두는 것이 좋습니다. 그래서 나는 ffmpeg-sharp를 포기했습니다.
그런 다음 SharpFFmpeg를 보았고 내가 원하는 것처럼 보였습니다. 모든 기능이 나를 위해 P / Invoked했습니다. 그러나 GPL? AVCodec.cs 및 AVFormat.cs 파일은 모두 내가 직접 이식 할 수있는 avcodec.c 및 avformat.c의 포트처럼 보입니다. 그런 다음 라이센스에 대해 걱정할 필요가 없습니다.
하지만 코딩을 시작하기 전에 바로 이것을 얻고 싶습니다. 내가해야합니까:
- ffmpeg와 상호 작용하기 위해 내 자신의 C ++ 라이브러리를 작성한 다음 비디오 등을 재생 / 변환하기 위해 내 C # 프로그램이 C ++ 라이브러리와 통신하도록합니다.
또는
- 많은 DllImport를 사용하여 avcodec.h 및 avformat.h (그게 전부입니까?)를 C #으로 포트하고 C #으로 완전히 작성합니까?
우선 C ++를 거의 사용하지 않기 때문에 C ++에 능숙하지 않지만 주위를 둘러 볼만큼 충분히 알고 있습니다. 내가 # 1이 더 나은 옵션이라고 생각하는 이유는 대부분의 FFmpeg 자습서가 C ++로되어 있고 C #에서 수행하는 것보다 메모리 관리를 더 많이 제어 할 수 있기 때문입니다.
어떻게 생각해? 또한 FFmpeg를 사용하는 데 유용한 링크 (아마도 튜토리얼)가 있습니까?
원래 질문은 이제 5 년이 넘었습니다. 그동안 ffmpeg 의 WinRT 솔루션 과 Microsoft 의 통합 샘플에 대한 솔루션이 있습니다 .
체크 아웃 할 수있는 몇 가지 다른 관리 래퍼
고유 한 interop 래퍼를 작성하는 것은 .NET에서 시간이 많이 걸리고 어려운 프로세스 일 수 있습니다. interop 용 C ++ 라이브러리를 작성하면 몇 가지 이점이 있습니다. 특히 C # 코드가 인터페이스를 크게 단순화 할 수 있기 때문입니다. 그러나 라이브러리의 하위 집합 만 필요한 경우 C #에서 interop을 수행하는 것이 더 쉬워 질 수 있습니다.
GPL로 컴파일 된 ffmpeg는 별도의 프로세스에서 명령 줄 유틸리티로 호출되는 경우에만 GPL이 아닌 프로그램 (상업용 프로젝트)에서 사용할 수 있습니다. ffmpeg 라이브러리 (Microsoft의 FFMpegInterop 포함)와 연결된 모든 래퍼는 ffmpeg의 LGPL 빌드 만 사용할 수 있습니다.
FFMpeg : Video Converter for .NET (저는이 라이브러리의 저자입니다)에 대한 제 .NET 래퍼를 사용해 볼 수 있습니다 . 쉬운 배포를 위해 DLL에 FFMpeg.exe를 포함하고 GPL 규칙을 위반하지 않습니다 (FFMpeg는 연결되지 않고 래퍼가 System.Diagnostics.Process와 별도의 프로세스에서 호출 함).
이 너겟 패키지를 사용할 수 있습니다.
Install-Package Xabe.FFmpeg
사용하기 쉬운 크로스 플랫폼 FFmpeg 래퍼를 만들려고합니다.
이에 대한 자세한 정보는 Xabe.FFmpeg 에서 찾을 수 있습니다.
문서의 추가 정보
변환은 간단합니다.
IConversionResult result = await Conversion.ToMp4(Resources.MkvWithAudio, output).Start();
여기에서 간단한 ffmpeg 래퍼 .NET을 시도 할 수 있습니다. http://ivolo.mit.edu/post/Convert-Audio-Video-to-Any-Format-using-C.aspx
Linux와 Windows 모두에서 실행 가능한 솔루션은 코드에서 콘솔 ffmpeg를 사용하는 데 익숙해지는 것입니다. 스레드를 쌓고 간단한 스레드 컨트롤러 클래스를 작성하면 사용하려는 ffmpeg의 기능을 쉽게 사용할 수 있습니다.
예를 들어, 여기에는 ffmpeg를 사용하여 내가 지정한 시간에서 축소판을 만드는 섹션이 포함되어 있습니다.
스레드 컨트롤러에는 다음과 같은 것이 있습니다.
List<ThrdFfmpeg> threads = new List<ThrdFfmpeg>();
실행중인 스레드 목록은 타이머를 사용하여 이러한 스레드를 폴링합니다. 폴링이 애플리케이션에 적합하지 않은 경우 이벤트를 설정할 수도 있습니다. 이 경우 Thrdffmpeg 클래스는 다음을 포함합니다.
public class ThrdFfmpeg
{
public FfmpegStuff ffm { get; set; }
public Thread thrd { get; set; }
}
FFmpegStuff에는 다양한 ffmpeg 기능이 포함되어 있으며 thrd는 분명히 스레드입니다.
FfmpegStuff의 속성은 FilesToProcess 클래스로, 호출 된 프로세스에 정보를 전달하고 스레드가 중지되면 정보를 수신하는 데 사용됩니다.
public class FileToProcess
{
public int videoID { get; set; }
public string fname { get; set; }
public int durationSeconds { get; set; }
public List<string> imgFiles { get; set; }
}
VideoID (저는 데이터베이스를 사용합니다)는 데이터베이스에서 가져온 비디오를 사용할 스레드 프로세스를 알려줍니다. fname은 FilesToProcess를 사용하는 내 함수의 다른 부분에서 사용되지만 여기서는 사용되지 않습니다. durationSeconds-비디오 길이를 수집하는 스레드로 채워집니다. imgFiles는 생성 된 축소판을 반환하는 데 사용됩니다.
이 작업의 목적이 쉽게 제어되는 스레드에서 ffmpeg를 사용하도록 장려 할 때 내 코드에 갇히고 싶지 않습니다.
이제 스레드 목록에 추가 할 수있는 조각이 있으므로 컨트롤러에서 다음과 같은 작업을 수행합니다.
AddThread()
{
ThrdFfmpeg thrd;
FileToProcess ftp;
foreach(FileToProcess ff in `dbhelper.GetFileNames(txtCategory.Text))`
{
//make a thread for each
ftp = new FileToProcess();
ftp = ff;
ftp.imgFiles = new List<string>();
thrd = new ThrdFfmpeg();
thrd.ffm = new FfmpegStuff();
thrd.ffm.filetoprocess = ftp;
thrd.thrd = new `System.Threading.Thread(thrd.ffm.CollectVideoLength);`
threads.Add(thrd);
}
if(timerNotStarted)
StartThreadTimer();
}
이제 스레드 폴링이 간단한 작업이됩니다.
private void timerThreads_Tick(object sender, EventArgs e)
{
int runningCount = 0;
int finishedThreads = 0;
foreach(ThrdFfmpeg thrd in threads)
{
switch (thrd.thrd.ThreadState)
{
case System.Threading.ThreadState.Running:
++runningCount;
//Note that you can still view data progress here,
//but remember that you must use your safety checks
//here more than anywhere else in your code, make sure the data
//is readable and of the right sort, before you read it.
break;
case System.Threading.ThreadState.StopRequested:
break;
case System.Threading.ThreadState.SuspendRequested:
break;
case System.Threading.ThreadState.Background:
break;
case System.Threading.ThreadState.Unstarted:
//Any threads that have been added but not yet started, start now
thrd.thrd.Start();
++runningCount;
break;
case System.Threading.ThreadState.Stopped:
++finishedThreads;
//You can now safely read the results, in this case the
//data contained in FilesToProcess
//Such as
ThumbnailsReadyEvent( thrd.ffm );
break;
case System.Threading.ThreadState.WaitSleepJoin:
break;
case System.Threading.ThreadState.Suspended:
break;
case System.Threading.ThreadState.AbortRequested:
break;
case System.Threading.ThreadState.Aborted:
break;
default:
break;
}
}
if(flash)
{//just a simple indicator so that I can see
//that at least one thread is still running
lbThreadStatus.BackColor = Color.White;
flash = false;
}
else
{
lbThreadStatus.BackColor = this.BackColor;
flash = true;
}
if(finishedThreads >= threads.Count())
{
StopThreadTimer();
ShowSample();
MakeJoinedThumb();
}
}
Putting your own events onto into the controller class works well, but in video work, when my own code is not actually doing any of the video file processing, poling then invoking an event in the controlling class works just as well.
Using this method I have slowly built up just about every video and stills function I think I will ever use, all contained in the one class, and that class as a text file is useable on the Lunux and Windows version, with just a small number of pre-process directives.
참고URL : https://stackoverflow.com/questions/2527963/using-ffmpeg-in-net
'programing tip' 카테고리의 다른 글
패키지 종속성을 자동으로 설치하도록 CRAN에 지시하는 방법은 무엇입니까? (0) | 2020.12.02 |
---|---|
dcast와 유사한 깔끔한 여러 열에 스프레드를 사용할 수 있습니까? (0) | 2020.12.02 |
Gradle 및 다중 프로젝트 구조 (0) | 2020.12.02 |
Android Lollipop에서 Notification.Builder.setSmallIcon으로 설정된 아이콘이 흰색 사각형으로 표시되는 이유는 무엇입니까? (0) | 2020.12.02 |
Docker의 기본 WORKDIR은 무엇입니까? (0) | 2020.12.02 |