ASP.Net Web Programlama C# WinForms ve Mono GTK Javascript

c# media işleme

Bu yazıda bir video dosyasını 4 eşit parçaya bölüp farklı bir video formatında kaydedeceğiz. Sonrasında kendim dizayn ettiğim bir video playerde durmadan yayınlayacağız. Son görünümü aşağıdaki gibi olacaktır.

C# ile bir console uygulaması oluşturuyorum. Dönüştürme için ffmpeg bilgisayarda kurulu olması gerekecektir. Projemize aşağıdaki komutla mediatoolkit kütüphanesini dahil ediyoruz.

Install-Package MediaToolkit -Version 1.1.0.1

Yolunu yazacağımız dosyayı 4 eşit parçaya böldüken sonra her birini kaydederken yeni bir dosya formatı ile kaydedeceğiz. Bu örnekte dosya girdisi mp4 çıktısı ise webm uzantılı olacaktır. Bu uzun sürecek bir işlem olduğundan gelişmeleri takip etmek için bazı olayları dışarı fırlatıyoruz ve mevcut durumu gözlemliyoruz.

class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            do
            {
                p.StartConverting();
            }
            while (true);
        }
        public void StartConverting()
        {
            Console.Write("Girdi dosya yolu seçiniz: ");
            string inputfile = Console.ReadLine();
            Console.Write("Çıktı dosya ismi seçiniz: ");
            string outputfilename = Console.ReadLine();
            var inputFile = new MediaFile { Filename = inputfile };
            double totalduration = 0;
            using (var engine = new Engine())
            {
                engine.GetMetadata(inputFile);
            }
            totalduration= inputFile.Metadata.Duration.TotalSeconds;
            var options = new ConversionOptions();
            double lastdurationsecond = 0;
            for (int i = 1; i <= 4; i++)
            {
                Console.WriteLine(i + " basladı");
                var outputFile = new MediaFile { Filename = (i.ToString() + "_" + outputfilename) };
                using (var engine = new Engine())
                {
                    engine.ConvertProgressEvent += ConvertProgressEvent;
                    engine.ConversionCompleteEvent += engine_ConversionCompleteEvent;
                    double totalsec = (totalduration / 4);
                    options.CutMedia(TimeSpan.FromSeconds(lastdurationsecond), TimeSpan.FromSeconds(totalsec));
                    engine.Convert(inputFile, outputFile, options);
                }
                lastdurationsecond += (totalduration / 4);
            }

            
        }

        private void ConvertProgressEvent(object sender, ConvertProgressEventArgs e)
        {
            Console.Write("\r{0}%   ", e.ProcessedDuration + "/" + TimeSpan.FromTicks(e.TotalDuration.Ticks / 4));
        }

        private void engine_ConversionCompleteEvent(object sender, ConversionCompleteEventArgs e)
        {
            Console.Clear();
            Console.WriteLine("\n------------\nConverting...\n------------");
            Console.WriteLine("Bitrate: {0} ", e.Bitrate);
            Console.WriteLine("Fps: {0} ", e.Fps);
            Console.WriteLine("Frame: {0} ", e.Frame);
            Console.WriteLine("ProcessedDuration: {0} ", e.ProcessedDuration);
            Console.WriteLine("SizeKb: {0} ", e.SizeKb);
            Console.WriteLine("TotalDuration: {0} \n", e.TotalDuration);
        }
    }    
}

    private void ConvertProgressEvent(object sender, ConvertProgressEventArgs e)
    {
        Console.Write("\r{0}%   ", e.ProcessedDuration + "/" + TimeSpan.FromTicks(e.TotalDuration.Ticks / 4));
    }

    private void engine_ConversionCompleteEvent(object sender, ConversionCompleteEventArgs e)
    {
        Console.Clear();
        Console.WriteLine("\n------------\nConverting...\n------------");
        Console.WriteLine("Bitrate: {0} ", e.Bitrate);
        Console.WriteLine("Fps: {0} ", e.Fps);
        Console.WriteLine("Frame: {0} ", e.Frame);
        Console.WriteLine("ProcessedDuration: {0} ", e.ProcessedDuration);
        Console.WriteLine("SizeKb: {0} ", e.SizeKb);
        Console.WriteLine("TotalDuration: {0} \n", e.TotalDuration);
    }

Elde ettiğimiz dosyalar html5 video elementi içerisinde multi source olarak ekleyip görüntüleyeceğiz. Ben burada control butonlarını kendim dizayn edeceğim. Ama javascript hazırdır.

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Video Test</title>
    <meta name='viewport' content='width=device-width, initial-scale=1'>
    <link rel="stylesheet" href="video.css">
</head>
<body>
	<figure id="videoContainer" data-fullscreen="false">
		<video id="video" controls>
            <source class="active" src="1_test.webm" type="video/webm">
            <source src="2_test.webm" type="video/webm">
            <source src="3_test.webm" type="video/webm">
            <source src="4_test.webm" type="video/webm">
            Video elementi tarayıcınız tarafından desteklenmiyor.
    </video>
    <div id="video-controls" class="controls" data-state="hidden">
        <button id="playpause" type="button" data-state="play">Play/Pause</button>
		<button id="stop" type="button" data-state="stop">Stop</button>
		<div class="progress">
			<progress id="progress" value="0" min="0">
				<span id="progress-bar"></span>
			</progress>
		</div>
		<button id="mute" type="button" data-state="mute">Mute/Unmute</button>
		<button id="volinc" type="button" data-state="volup">Vol+</button>
		<button id="voldec" type="button" data-state="voldown">Vol-</button>
		<button id="fs" type="button" data-state="go-fullscreen">Fullscreen</button>
    </div>
	</figure>
    <script src="player.js"></script>
    <script>
        var myvid = document.getElementById('video');
        myvid.addEventListener('ended', function(e) {
            var activesource = document.querySelector("#video source.active");
            var nextsource = document.querySelector("#video source.active + source") 
            || document.querySelector("#video source:first-child");
            activesource.className = "";
            nextsource.className = "active";
            myvid.src = nextsource.src;
            myvid.play();
        });
    </script>
</body>
</html>

Hazır bulduğum js dosyası aşağıdadır. Commentleri silmeyerek meraklı arkadaşlar için bilgileri içinde bırakıyorum.

(function () {
'use strict';
// Does the browser actually support the video element?
var supportsVideo = !!document.createElement('video').canPlayType;

if (supportsVideo) {
    // Obtain handles to main elements
    var videoContainer = document.getElementById('videoContainer');
    var video = document.getElementById('video');
    var videoControls = document.getElementById('video-controls');

    // Hide the default controls
    video.controls = false;

    // Display the user defined video controls
    videoControls.setAttribute('data-state', 'visible');

    // Obtain handles to buttons and other elements
    var playpause = document.getElementById('playpause');
    var stop = document.getElementById('stop');
    var mute = document.getElementById('mute');
    var volinc = document.getElementById('volinc');
    var voldec = document.getElementById('voldec');
    var progress = document.getElementById('progress');
    var progressBar = document.getElementById('progress-bar');
    var fullscreen = document.getElementById('fs');

    // If the browser doesn't support the progress element, set its state for some different styling
    var supportsProgress = (document.createElement('progress').max !== undefined);
    if (!supportsProgress) progress.setAttribute('data-state', 'fake');

    // Check if the browser supports the Fullscreen API
    var fullScreenEnabled = !!(document.fullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled || document.webkitSupportsFullscreen || document.webkitFullscreenEnabled || document.createElement('video').webkitRequestFullScreen);
    // If the browser doesn't support the Fulscreen API then hide the fullscreen button
    if (!fullScreenEnabled) {
        fullscreen.style.display = 'none';
    }

    // Check the volume
    var checkVolume = function(dir) {
        if (dir) {
            var currentVolume = Math.floor(video.volume * 10) / 10;
            if (dir === '+') {
                if (currentVolume < 1) video.volume += 0.1;
            }
            else if (dir === '-') {
                if (currentVolume > 0) video.volume -= 0.1;
            }
            // If the volume has been turned off, also set it as muted
            // Note: can only do this with the custom control set as when the 'volumechange' event is raised, there is no way to know if it was via a volume or a mute change
            if (currentVolume <= 0) video.muted = true;
            else video.muted = false;
        }
        changeButtonState('mute');
    }

    // Change the volume
    var alterVolume = function(dir) {
        checkVolume(dir);
    }

    // Set the video container's fullscreen state
    var setFullscreenData = function(state) {
        videoContainer.setAttribute('data-fullscreen', !!state);
        // Set the fullscreen button's 'data-state' which allows the correct button image to be set via CSS
        fullscreen.setAttribute('data-state', !!state ? 'cancel-fullscreen' : 'go-fullscreen');
    }

    // Checks if the document is currently in fullscreen mode
    var isFullScreen = function() {
        return !!(document.fullScreen || document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement || document.fullscreenElement);
    }

    // Fullscreen
    var handleFullscreen = function() {
        // If fullscreen mode is active...  
        if (isFullScreen()) {
                // ...exit fullscreen mode
                // (Note: this can only be called on document)
                if (document.exitFullscreen) document.exitFullscreen();
                else if (document.mozCancelFullScreen) document.mozCancelFullScreen();
                else if (document.webkitCancelFullScreen) document.webkitCancelFullScreen();
                else if (document.msExitFullscreen) document.msExitFullscreen();
                setFullscreenData(false);
            }
            else {
                // ...otherwise enter fullscreen mode
                // (Note: can be called on document, but here the specific element is used as it will also ensure that the element's children, e.g. the custom controls, go fullscreen also)
                if (videoContainer.requestFullscreen) videoContainer.requestFullscreen();
                else if (videoContainer.mozRequestFullScreen) videoContainer.mozRequestFullScreen();
                else if (videoContainer.webkitRequestFullScreen) {
                    // Safari 5.1 only allows proper fullscreen on the video element. This also works fine on other WebKit browsers as the following CSS (set in styles.css) hides the default controls that appear again, and 
                    // ensures that our custom controls are visible:
                    // figure[data-fullscreen=true] video::-webkit-media-controls { display:none !important; }
                    // figure[data-fullscreen=true] .controls { z-index:2147483647; }
                    video.webkitRequestFullScreen();
                }
                else if (videoContainer.msRequestFullscreen) videoContainer.msRequestFullscreen();
                setFullscreenData(true);
            }
        }

    // Only add the events if addEventListener is supported (IE8 and less don't support it, but that will use Flash anyway)
    if (document.addEventListener) {
        // Wait for the video's meta data to be loaded, then set the progress bar's max value to the duration of the video
        video.addEventListener('loadedmetadata', function() {
            progress.setAttribute('max', video.duration);
        });

        // Changes the button state of certain button's so the correct visuals can be displayed with CSS
        var changeButtonState = function(type) {
            // Play/Pause button
            if (type == 'playpause') {
                if (video.paused || video.ended) {
                    playpause.setAttribute('data-state', 'play');
                }
                else {
                    playpause.setAttribute('data-state', 'pause');
                }
            }
            // Mute button
            else if (type == 'mute') {
                mute.setAttribute('data-state', video.muted ? 'unmute' : 'mute');
            }
        }

        // Add event listeners for video specific events
        video.addEventListener('play', function() {
            changeButtonState('playpause');
        }, false);
        video.addEventListener('pause', function() {
            changeButtonState('playpause');
        }, false);
        video.addEventListener('volumechange', function() {
            checkVolume();
        }, false);

        // Add events for all buttons           
        playpause.addEventListener('click', function(e) {
            if (video.paused || video.ended) video.play();
            else video.pause();
        });         

        // The Media API has no 'stop()' function, so pause the video and reset its time and the progress bar
        stop.addEventListener('click', function(e) {
            video.pause();
            video.currentTime = 0;
            progress.value = 0;
            // Update the play/pause button's 'data-state' which allows the correct button image to be set via CSS
            changeButtonState('playpause');
        });
        mute.addEventListener('click', function(e) {
            video.muted = !video.muted;
            changeButtonState('mute');
        });
        volinc.addEventListener('click', function(e) {
            alterVolume('+');
        });
        voldec.addEventListener('click', function(e) {
            alterVolume('-');
        });
        fs.addEventListener('click', function(e) {
            handleFullscreen();
        });

        // As the video is playing, update the progress bar
        video.addEventListener('timeupdate', function() {
            // For mobile browsers, ensure that the progress element's max attribute is set
            if (!progress.getAttribute('max')) progress.setAttribute('max', video.duration);
            progress.value = video.currentTime;
            progressBar.style.width = Math.floor((video.currentTime / video.duration) * 100) + '%';
        });

        // React to the user clicking within the progress bar
        progress.addEventListener('click', function(e) {
            //var pos = (e.pageX  - this.offsetLeft) / this.offsetWidth; // Also need to take the parent into account here as .controls now has position:relative
            var pos = (e.pageX  - (this.offsetLeft + this.offsetParent.offsetLeft)) / this.offsetWidth;
            video.currentTime = pos * video.duration;
        });

        // Listen for fullscreen change events (from other controls, e.g. right clicking on the video itself)
        document.addEventListener('fullscreenchange', function(e) {
            setFullscreenData(!!(document.fullScreen || document.fullscreenElement));
        });
        document.addEventListener('webkitfullscreenchange', function() {
            setFullscreenData(!!document.webkitIsFullScreen);
        });
        document.addEventListener('mozfullscreenchange', function() {
            setFullscreenData(!!document.mozFullScreen);
        });
        document.addEventListener('msfullscreenchange', function() {
            setFullscreenData(!!document.msFullscreenElement);
        });
    }
 }})();

stil dosyası da hazır ama elementleri değiştirdim ve yerleriyle oynadım. İhtiyacım olmayan şeyleri kaldırdım.

html, body {
	margin:0;
	padding:0;
	width:100%;
	height:100%;
}
body {
	color:#666;
	background-color:#ccc;
	font-family:"Lucida Grande","Lucida Sans Unicode","DejaVu Sans",Lucida,Arial,Helvetica,sans-serif;
}
h1 {
	color:#666;
	font-size:20px;
	font-size:1.25rem;
	text-align:center;
	margin:0;
	padding:0.5rem 0;
}
a {
	color:#0095dd;
	text-decoration:none;
}
a:hover, a:focus {
	color:#2255aa;
	text-decoration:underline;
}
figure {
	max-width:1024px;
	max-width:64rem;
	width:100%;
	height:100%;
	max-height:494px;
	max-height:30.875rem;
	margin:20px auto;
	margin:1.25rem auto;
	padding:20px;
	padding:1.051%;
}
figcaption {
	display:block;
	font-size:12px;
	font-size:0.75rem;
	color:#fff;
}
video {
	width:100%;
}

/* controls */
.controls, .controls > * {
	padding:0;
	margin:0;
}
.controls {
	overflow:hidden;
	background:transparent;
	width:99%;
	height:8.0971659919028340080971659919028%; /* of figure's height */
	position:relative;
}
.controls[data-state=hidden] {
	display:none;
}
.controls[data-state=visible] {
	display:block;
}
.controls > * {
	float:left;
	width:3.90625%;
	height:100%;
	margin-left:0.1953125%;
	display:block;
}
.controls > *:first-child {
	margin-left:0;
}
.controls .progress {
	cursor:pointer;
	width:90%;
}
.controls button {
	text-align:center;
	overflow:hidden;
	white-space:nowrap;
  	text-overflow:ellipsis;
  	border:none;
  	cursor:pointer;
  	text-indent:-99999px;
  	background:transparent;
  	background-size:contain;
  	background-repeat:no-repeat;
}
.controls button:hover, .controls button:focus {
	opacity:0.5;
}
.controls button[data-state="play"] {
	background-image: url('play.png');
}
.controls button[data-state="pause"] {
	background-image: url('pause.png');
}
.controls button[data-state="go-fullscreen"] {
	background-image: url('gofullscr.png');	
}
.controls button[data-state="cancel-fullscreen"] {
	background-image: url('cancfullsccr.png');	
}
.controls button[data-state="stop"] {
	display: none;
}
.controls button[data-state="mute"] {
	display: none;
}
.controls button[data-state="unmute"] {
	display: none;
}
.controls button[data-state="volup"] {
	display: none;
}
.controls button[data-state="voldown"] {
	display: none;
}
.controls progress {
	display:block;
	width:100%;
	height: 84%;
	margin-top:2px;
	margin-top:0.125rem;
	border:none;
	overflow:hidden;
	-moz-border-radius:2px;
	-webkit-border-radius:2px;
	border-radius:2px;
	color:#0095dd; /* Internet Explorer uses this value as the progress bar's value colour */
}
#video-controls{
    background-color: black;
	height: 20px;
	margin-left: 1%;
	margin-right: 5%;
	margin-top: -30px;
}
.controls progress[data-state="fake"] {
	background:#e6e6e6;
	height:5%;
}
.controls progress span {
	width:0%;
	height:100%;
	display:inline-block;
	background-color:#2a84cd;	
}

.controls progress::-moz-progress-bar {
	background-color:#0095dd;
}
/* Chrome requires its own rule for this, otherwise it ignores it */
.controls progress::-webkit-progress-value {
	background-color:white;
}

/* fullscreen */
html:-ms-fullscreen {
	width:100%;
}
:-webkit-full-screen {
	background-color:transparent;
}
video:-webkit-full-screen + .controls {
	background:#ccc; /* required for Chrome which doesn't heed the transparent value set above */
}
video:-webkit-full-screen + .controls progress {
	margin-top:0.5rem;
}

/* hide controls on fullscreen with WebKit */
figure[data-fullscreen=true] video::-webkit-media-controls {
	display:none !important;
}
figure[data-fullscreen=true] {
	max-width:100%;
	width:100%;
	margin:0;
	padding:0;
	max-height:100%;
}
figure[data-fullscreen=true] video {
	height:auto;
}
figure[data-fullscreen=true] figcaption {
	display:none;
}
figure[data-fullscreen=true] .controls {
	position:absolute;
	bottom:2%;
	width:100%;
	z-index:2147483647;
}
figure[data-fullscreen=true] .controls li {
	width:5%;
}
figure[data-fullscreen=true] .controls .progress {
	width:90%;
}

/* Media Queries */
@media screen and (max-width:1024px) {
	figure {
		padding-left:0;
		padding-right:0;
		height:auto;
	}
	.controls {
		/* we want the buttons to be proportionally bigger, so give their parent a set height */
		height:30px;
		height:1.876rem;
	}
}
@media screen and (max-width:42.5em) {
	.controls {
		height:auto;
	}
	.controls > * {
		display:block;
		width:16.6667%;
		margin-left:0;
		height:40px;
		height:2.5rem;
		margin-top:2.5rem;
	}
	.controls .progress {
		/*display:table-caption;*/ /* this trick doesn't work as elements are floated and the layout doesn't work */
		position:absolute;
		top:0;
		width:100%;
		float:none;
		margin-top:0;
	}
	.controls .progress progress {
		width:98%;
		margin:0 auto;
	}
	.controls button {
		background-position:center center;
	}
	figcaption {
		text-align:center;
		margin-top:0.5rem;
	}
}

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir