Recherche avancée

Médias (1)

Mot : - Tags -/3GS

Autres articles (68)

  • Submit bugs and patches

    13 avril 2011

    Unfortunately a software is never perfect.
    If you think you have found a bug, report it using our ticket system. Please to help us to fix it by providing the following information : the browser you are using, including the exact version as precise an explanation as possible of the problem if possible, the steps taken resulting in the problem a link to the site / page in question
    If you think you have solved the bug, fill in a ticket and attach to it a corrective patch.
    You may also (...)

  • Des sites réalisés avec MediaSPIP

    2 mai 2011, par

    Cette page présente quelques-uns des sites fonctionnant sous MediaSPIP.
    Vous pouvez bien entendu ajouter le votre grâce au formulaire en bas de page.

  • La sauvegarde automatique de canaux SPIP

    1er avril 2010, par

    Dans le cadre de la mise en place d’une plateforme ouverte, il est important pour les hébergeurs de pouvoir disposer de sauvegardes assez régulières pour parer à tout problème éventuel.
    Pour réaliser cette tâche on se base sur deux plugins SPIP : Saveauto qui permet une sauvegarde régulière de la base de donnée sous la forme d’un dump mysql (utilisable dans phpmyadmin) mes_fichiers_2 qui permet de réaliser une archive au format zip des données importantes du site (les documents, les éléments (...)

Sur d’autres sites (8632)

  • What is Multi-Touch Attribution ? (And How To Get Started)

    2 février 2023, par Erin — Analytics Tips

    Good marketing thrives on data. Or more precisely — its interpretation. Using modern analytics software, we can determine which marketing actions steer prospects towards the desired action (a conversion event). 

    An attribution model in marketing is a set of rules that determine how various marketing tactics and channels impact the visitor’s progress towards a conversion. 

    Yet, as customer journeys become more complicated and involve multiple “touches”, standard marketing reports no longer tell the full picture. 

    That’s when multi-touch attribution analysis comes to the fore. 

    What is Multi-Touch Attribution ?

    Multi-touch attribution (also known as multi-channel attribution or cross-channel attribution) measures the impact of all touchpoints on the consumer journey on conversion. 

    Unlike single-touch reporting, multi-touch attribution models give credit to each marketing element — a social media ad, an on-site banner, an email link click, etc. By seeing impacts from every touchpoint and channel, marketers can avoid false assumptions or subpar budget allocations.

    To better understand the concept, let’s interpret the same customer journey using a standard single-touch report vs a multi-touch attribution model. 

    Picture this : Jammie is shopping around for a privacy-centred web analytics solution. She saw a recommendation on Twitter and ended up on the Matomo website. After browsing a few product pages and checking comparisons with other web analytics tools, she signs up for a webinar. One week after attending, Jammie is convinced that Matomo is the right tool for her business and goes directly to the Matomo website a starts a free trial. 

    • A standard single-touch report would attribute 100% of the conversion to direct traffic, which doesn’t give an accurate view of the multiple touchpoints that led Jammie to start a free trial. 
    • A multi-channel attribution report would showcase all the channels involved in the free trial conversion — social media, website content, the webinar, and then the direct traffic source.

    In other words : Multi-touch attribution helps you understand how prospects move through the sales funnel and which elements tinder them towards the desired outcome. 

    Types of Attribution Models

    As marketers, we know that multiple factors play into a conversion — channel type, timing, user’s stage on the buyer journey and so on. Various attribution models exist to reflect this variability. 

    Types of Attribution Models

    First Interaction attribution model (otherwise known as first touch) gives all credit for the conversion to the first channel (for example — a referral link) and doesn’t report on all the other interactions a user had with your company (e.g., clicked a newsletter link, engaged with a landing page, or browsed the blog campaign).

    First-touch helps optimise the top of your funnel and establish which channels bring the best leads. However, it doesn’t offer any insight into other factors that persuaded a user to convert. 

    Last Interaction attribution model (also known as last touch) allocates 100% credit to the last channel before conversion — be it direct traffic, paid ad, or an internal product page.

    The data is useful for optimising the bottom-of-the-funnel (BoFU) elements. But you have no visibility into assisted conversions — interactions a user had prior to conversion. 

    Last Non-Direct attribution model model excludes direct traffic and assigns 100% credit for a conversion to the last channel a user interacted with before converting. For instance, a social media post will receive 100% of credit if a shopper buys a product three days later. 

    This model is more telling about the other channels, involved in the sales process. Yet, you’re seeing only one step backwards, which may not be sufficient for companies with longer sales cycles.

    Linear attribution model distributes an equal credit for a conversion between all tracked touchpoints.

    For instance, with a four touchpoint conversion (e.g., an organic visit, then a direct visit, then a social visit, then a visit and conversion from an ad campaign) each touchpoint would receive 25% credit for that single conversion.

    This is the simplest multi-channel attribution modelling technique many tools support. The nuance is that linear models don’t reflect the true impact of various events. After all, a paid ad that introduced your brand to the shopper and a time-sensitive discount code at the checkout page probably did more than the blog content a shopper browsed in between. 

    Position Based attribution model allocates a 40% credit to the first and the last touchpoints and then spreads the remaining 20% across the touchpoints between the first and last. 

    This attribution model comes in handy for optimising conversions across the top and the bottom of the funnel. But it doesn’t provide much insight into the middle, which can skew your decision-making. For instance, you may overlook cases when a shopper landed via a social media post, then was re-engaged via email, and proceeded to checkout after an organic visit. Without email marketing, that sale may not have happened.

    Time decay attribution model adjusts the credit, based on the timing of the interactions. Touchpoints that preceded the conversion get the highest score, while the first ones get less weight (e.g., 5%-5%-10%-15%-25%-30%).

    This multi-channel attribution model works great for tracking the bottom of the funnel, but it underestimates the impact of brand awareness campaigns or assisted conversions at mid-stage. 

    Why Use Multi-Touch Attribution Modelling

    Multi-touch attribution provides you with the full picture of your funnel. With accurate data across all touchpoints, you can employ targeted conversion rate optimisation (CRO) strategies to maximise the impact of each campaign. 

    Most marketers and analysts prefer using multi-touch attribution modelling — and for some good reasons.

    Issues multi-touch attribution solves 

    • Funnel visibility. Understand which tactics play an important role at the top, middle and bottom of your funnel, instead of second-guessing what’s working or not. 
    • Budget allocations. Spend money on channels and tactics that bring a positive return on investment (ROI). 
    • Assisted conversions. Learn how different elements and touchpoints cumulatively contribute to the ultimate goal — a conversion event — to optimise accordingly. 
    • Channel segmentation. Determine which assets drive the most qualified and engaged leads to replicate them at scale.
    • Campaign benchmarking. Compare how different marketing activities from affiliate marketing to social media perform against the same metrics.

    How To Get Started With Multi-Touch Attribution 

    To make multi-touch attribution part of your analytics setup, follow the next steps :

    1. Define Your Marketing Objectives 

    Multi-touch attribution helps you better understand what led people to convert on your site. But to capture that, you need to first map the standard purchase journeys, which include a series of touchpoints — instances, when a prospect forms an opinion about your business.

    Touchpoints include :

    • On-site interactions (e.g., reading a blog post, browsing product pages, using an on-site calculator, etc.)
    • Off-site interactions (e.g., reading a review, clicking a social media link, interacting with an ad, etc.)

    Combined these interactions make up your sales funnel — a designated path you’ve set up to lead people toward the desired action (aka a conversion). 

    Depending on your business model, you can count any of the following as a conversion :

    • Purchase 
    • Account registration 
    • Free trial request 
    • Contact form submission 
    • Online reservation 
    • Demo call request 
    • Newsletter subscription

    So your first task is to create a set of conversion objectives for your business and add them as Goals or Conversions in your web analytics solution. Then brainstorm how various touchpoints contribute to these objectives. 

    Web analytics tools with multi-channel attribution, like Matomo, allow you to obtain an extra dimension of data on touchpoints via Tracked Events. Using Event Tracking, you can analyse how many people started doing a desired action (e.g., typing details into the form) but never completed the task. This way you can quickly identify “leaking” touchpoints in your funnel and fix them. 

    2. Select an Attribution Model 

    Multi-attribution models have inherent tradeoffs. Linear attribution model doesn’t always represent the role and importance of each channel. Position-based attribution model emphasises the role of the last and first channel while diminishing the importance of assisted conversions. Time-decay model, on the contrary, downplays the role awareness-related campaigns played.

    To select the right attribution model for your business consider your objectives. Is it more important for you to understand your best top of funnel channels to optimise customer acquisition costs (CAC) ? Or would you rather maximise your on-site conversion rates ? 

    Your industry and the average cycle length should also guide your choice. Position-based models can work best for eCommerce and SaaS businesses where both CAC and on-site conversion rates play an important role. Manufacturing companies or educational services providers, on the contrary, will benefit more from a time-decay model as it better represents the lengthy sales cycles. 

    3. Collect and Organise Data From All Touchpoints 

    Multi-touch attribution models are based on available funnel data. So to get started, you will need to determine which data sources you have and how to best leverage them for attribution modelling. 

    Types of data you should collect : 

    • General web analytics data : Insights on visitors’ on-site actions — visited pages, clicked links, form submissions and more.
    • Goals (Conversions) : Reports on successful conversions across different types of assets. 
    • Behavioural user data : Some tools also offer advanced features such as heatmaps, session recording and A/B tests. These too provide ample data into user behaviours, which you can use to map and optimise various touchpoints.

    You can also implement extra tracking, for instance for contact form submissions, live chat contacts or email marketing campaigns to identify repeat users in your system. Just remember to stay on the good side of data protection laws and respect your visitors’ privacy. 

    Separately, you can obtain top-of-the-funnel data by analysing referral traffic sources (channel, campaign type, used keyword, etc). A Tag Manager comes in handy as it allows you to zoom in on particular assets (e.g., a newsletter, an affiliate, a social campaign, etc). 

    Combined, these data points can be parsed by an app, supporting multi-touch attribution (or a custom algorithm) and reported back to you as specific findings. 

    Sounds easy, right ? Well, the devil is in the details. Getting ample, accurate data for multi-touch attribution modelling isn’t easy. 

    Marketing analytics has an accuracy problem, mainly for two reasons :

    • Cookie consent banner rejection 
    • Data sampling application

    Please note that we are not able to provide legal advice, so it’s important that you consult with your own DPO to ensure compliance with all relevant laws and regulations.

    If you’re collecting web analytics in the EU, you know that showing a cookie consent banner is a GDPR must-do. But many consumers don’t often rush to accept cookie consent banners. The average consent rate for cookies in 2021 stood at 54% in Italy, 45% in France, and 44% in Germany. The consent rates are likely lower in 2023, as Google was forced to roll out a “reject all” button for cookie tracking in Europe, while privacy organisations lodge complaints against individual businesses for deceptive banners. 

    For marketers, cookie rejection means substantial gaps in analytics data. The good news is that you can fill in those gaps by using a privacy-centred web analytics tool like Matomo. 

    Matomo takes extra safeguards to protect user privacy and supports fully cookieless tracking. Because of that, Matomo is legally exempt from tracking consent in France. Plus, you can configure to use our analytics tool without consent banners in other markets outside of Germany and the UK. This way you get to retain the data you need for audience modelling without breaching any privacy regulations. 

    Data sampling application partially stems from the above. When a web analytics or multi-channel attribution tool cannot secure first-hand data, the “guessing game” begins. Google Analytics, as well as other tools, often rely on synthetic AI-generated data to fill in the reporting gaps. Respectively, your multi-attribution model doesn’t depict the real state of affairs. Instead, it shows AI-produced guesstimates of what transpired whenever not enough real-world evidence is available.

    4. Evaluate and Select an Attribution Tool 

    Google Analytics (GA) offers several multi-touch attribution models for free (linear, time-decay and position-based). The disadvantage of GA multi-touch attribution is its lower accuracy due to cookie rejection and data sampling application.

    At the same time, you cannot create custom credit allocations for the proposed models, unless you have the paid version of GA, Google Analytics 360. This version of GA comes with a custom Attribution Modeling Tool (AMT). The price tag, however, starts at USD $50,000 per year. 

    Matomo Cloud offers multi-channel conversion attribution as a feature and it is available as a plug-in on the marketplace for Matomo On-Premise. We support linear, position-based, first-interaction, last-interaction, last non-direct and time-decay modelling, based fully on first-hand data. You also get more precise insights because cookie consent isn’t an issue with us. 

    Most multi-channel attribution tools, like Google Analytics and Matomo, provide out-of-the-box multi-touch attribution models. But other tools, like Matomo On-Premise, also provide full access to raw data so you can develop your own multi-touch attribution models and do custom attribution analysis. The ability to create custom attribution analysis is particularly beneficial for data analysts or organisations with complex and unique buyer journeys. 

    Conclusion

    Ultimately, multi-channel attribution gives marketers greater visibility into the customer journey. By analysing multiple touchpoints, you can establish how various marketing efforts contribute to conversions. Then use this information to inform your promotional strategy, budget allocations and CRO efforts. 

    The key to benefiting the most from multi-touch attribution is accurate data. If your analytics solution isn’t telling you the full story, your multi-touch model won’t either. 

    Collect accurate visitor data for multi-touch attribution modelling with Matomo. Start your free 21-day trial now

  • Processing of multipart/form-data request failed. Unexpected EOF read on the socket

    23 mai 2017, par Rares

    I am trying to upload a video file to the server(Spring Boot) from android.

    A video filmed with the phone has >50 MB if you film at least 2 minutes so I have to compress the file before uploading.
    Before compressing I tried to upload uncompressed files and it worked fine(10-30MB videos). Now I want to compress files because I want to send bigger videos to the server.
    I use multipart/form-data in android to send the file to the server.

    EDIT :

    protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
           super.onActivityResult(requestCode, resultCode, data);
           if (requestCode == REQUEST_PICK_VIDEO && resultCode == RESULT_OK && data != null) {
               progressDialog = new ProgressDialog(MainActivity.this);
               progressDialog.setTitle("Uploading");
               progressDialog.setMessage("Please wait...");
               progressDialog.show();
               Thread thread = new Thread(new Runnable() {
                   @Override
                   public void run() {
                       String filePath = getRealPathFromURI(getApplicationContext(), data.getData());

                       ///get the name of file without extension
                       StringBuilder stringBuilder = new StringBuilder(filePath);
                       int start = filePath.lastIndexOf('.');
                       stringBuilder.delete(start, filePath.length());
                       //--------------
                       //get file extension(e.g mp4)
                       File file = new File(filePath);
                       String contentType = getFileType(file.getAbsolutePath());
                       //--------------
                       //create compressed file path=initial file path+ _compressed+(random nr.)+ extension .mp4
                       Random random = new Random();
                       int fileNr = random.nextInt(999);
                       String compressedFilePath = stringBuilder.toString() + "_compressed" + fileNr +"."+ contentType;

                       //compress file from gallery and save it with the above name
                       String[] command = {"-y", "-i", filePath, "-s", "640x480", "-r", "25", "-vcodec",
                               "mpeg4", "-b:v", "150k", "-b:a", "48000", "-ac", "2", "-ar", "22050", compressedFilePath};
                       executeFFmpegBinary(command);

                       File file2 = new File(compressedFilePath);

                       if (file2.exists()) {
                           OkHttpClient httpClient = new OkHttpClient();
                           RequestBody fileBody = RequestBody.create(MediaType.parse(contentType), file2);
                           RequestBody requestBody = new MultipartBody.Builder()
                                   .setType(MultipartBody.FORM)
                                   .addFormDataPart("type", contentType)
                                   .addFormDataPart("uploaded_file", file2.getName(), fileBody)
                                   .build();
                           Request request = new Request.Builder()
                                   .url(SERVER_ADDRESS_UPLOAD)
                                   .post(requestBody)
                                   .build();
                           try {
                               final Response response = httpClient.newCall(request).execute();
                               if (!response.isSuccessful()) {
                                   printFromThread(response.toString());
                                   throw new IOException("Error: " + response);
                               } else {
                                   printFromThread(response.body().string());
                               }
                               progressDialog.dismiss();
                           } catch (IOException e) {
                               e.printStackTrace();
                           }
                       }

                   }

               });
               thread.start();
           }

       }

    When I use FFmpeg compression and I send the compressed file to the server I receive the following error in the server :Processing of multipart/form-data request failed. Unexpected EOF read on the socket

    Server bean :

     @RequestMapping(value = "/upload-image", method = RequestMethod.POST)
      @ResponseBody
      public String handleUploadImageRequest(@RequestParam("uploaded_file")
      MultipartFile file) throws IOException {
    File fileReceived = new File(VIDEOS_DIR+"/"+file.getOriginalFilename());
    fileReceived.createNewFile();
    FileOutputStream fileOutputStream = new FileOutputStream(fileReceived);
    fileOutputStream.write(file.getBytes());
    fileOutputStream.close();

    prelucrareVideo(fileReceived);
    return "....";

    }

    Here is the exception :

    2017-05-22 23:36:24.122 DEBUG 5032 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket
    2017-05-22 23:36:24.122 DEBUG 5032 --- [nio-8080-exec-1] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [null]: org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket
    2017-05-22 23:36:24.123 DEBUG 5032 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [null]: org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket
    2017-05-22 23:36:24.123 DEBUG 5032 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                : Could not complete request

    org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket
       at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:111) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:85) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:79) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1100) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:932) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_121]
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_121]
       at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at java.lang.Thread.run(Thread.java:745) [?:1.8.0_121]
    Caused by: java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket
       at org.apache.catalina.connector.Request.parseParts(Request.java:2874) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.parseParameters(Request.java:3177) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.getParameter(Request.java:1110) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:381) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:75) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       ... 23 more
    Caused by: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket
       at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:297) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.parseParts(Request.java:2801) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.parseParameters(Request.java:3177) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.getParameter(Request.java:1110) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:381) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:75) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       ... 23 more
    Caused by: java.io.EOFException: Unexpected EOF read on the socket
       at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:717) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.http11.Http11InputBuffer.access$300(Http11InputBuffer.java:40) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.http11.Http11InputBuffer$SocketInputBuffer.doRead(Http11InputBuffer.java:1061) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:139) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.http11.Http11InputBuffer.doRead(Http11InputBuffer.java:256) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.Request.doRead(Request.java:540) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:319) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.InputBuffer.checkByteBufferEof(InputBuffer.java:627) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:342) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:183) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at java.io.FilterInputStream.read(FilterInputStream.java:133) ~[?:1.8.0_121]
       at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.read(LimitedInputStream.java:132) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.http.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:977) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.http.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:881) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at java.io.FilterInputStream.read(FilterInputStream.java:133) ~[?:1.8.0_121]
       at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.read(LimitedInputStream.java:132) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at java.io.FilterInputStream.read(FilterInputStream.java:107) ~[?:1.8.0_121]
       at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:98) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:68) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:293) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.parseParts(Request.java:2801) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.parseParameters(Request.java:3177) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.getParameter(Request.java:1110) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:381) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:75) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       ... 23 more

    2017-05-22 23:36:24.130 ERROR 5032 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket] with root cause

    java.io.EOFException: Unexpected EOF read on the socket
       at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:717) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.http11.Http11InputBuffer.access$300(Http11InputBuffer.java:40) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.http11.Http11InputBuffer$SocketInputBuffer.doRead(Http11InputBuffer.java:1061) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:139) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.http11.Http11InputBuffer.doRead(Http11InputBuffer.java:256) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.Request.doRead(Request.java:540) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:319) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.InputBuffer.checkByteBufferEof(InputBuffer.java:627) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:342) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:183) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at java.io.FilterInputStream.read(FilterInputStream.java:133) ~[?:1.8.0_121]
       at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.read(LimitedInputStream.java:132) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.http.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:977) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.http.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:881) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at java.io.FilterInputStream.read(FilterInputStream.java:133) ~[?:1.8.0_121]
       at org.apache.tomcat.util.http.fileupload.util.LimitedInputStream.read(LimitedInputStream.java:132) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at java.io.FilterInputStream.read(FilterInputStream.java:107) ~[?:1.8.0_121]
       at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:98) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.http.fileupload.util.Streams.copy(Streams.java:68) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:293) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.parseParts(Request.java:2801) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.parseParameters(Request.java:3177) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.Request.getParameter(Request.java:1110) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:381) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:75) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_121]
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_121]
       at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.11.jar:8.5.11]
       at java.lang.Thread.run(Thread.java:745) [?:1.8.0_121]
    </init>

    What is the solution ? Thanks in advance.

  • FFmpeg decoded video is garbled mess with no audio. How can I fix it ? [closed]

    14 septembre 2023, par Señor Tonto

    I am trying to use FFmpeg 6.0 (which seems to have a terrible lack of documentation) to decode a .mp4/.mov file & play its audio. I am testing this on a .mov file (I tried also with a .mp4, same result) of an old animation I found. This turns out as a garbled mess that looks like an old film movie with no audio. Now, I used some old tutorials & managed to with much trial get the code I have now, which is of course half-working. I am using SDL to output the video. I'm not sure if it's a problem on the SDL end or the FFmpeg end at the moment (but I'm sure the video is a mix of the two & the audio because of SDL) I would appreciate some help as there's very little documentation I can find that isn't outdated & the deprecated list on FFmpeg hardly helps when I need to fix API-related changes. Here's my code

    &#xA;

    LRESULT CALLBACK WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {&#xA;    OPENFILENAME ofn;&#xA;&#xA;    wchar_t g_filePath[MAX_PATH] = L"";&#xA;    char szFile[MAX_PATH] = "";&#xA;    wchar_t wFile[MAX_PATH] = L"";&#xA;    char data[MAX_PATH];&#xA;    DWORD bytesRead = 0;&#xA;    BOOL bSuccess = FALSE;&#xA;    static int iVscrollPos, cyClient, cyChar, cxChar, cxCaps, iMaxVerticalScroll = 0, iNumLines = 0;&#xA;    HDC hdc;&#xA;    TEXTMETRIC tm;&#xA;    static int tabIndex;&#xA;    std::wstring filePath;&#xA;&#xA;    //FFmpeg variables&#xA;    static AVFormatContext* format_ctx = nullptr; &#xA;    static AVCodecContext* video_codec_ctx = nullptr;&#xA;    static AVCodecContext* audio_codec_ctx = nullptr;&#xA;    static AVFrame* video_frame = nullptr;&#xA;    static AVFrame* audio_frame = nullptr;&#xA;    static AVPacket packet;&#xA;    static struct SwsContext* sws_ctx = nullptr;&#xA;    static int video_stream_idx = -1;&#xA;    static int audio_stream_idx = -1;&#xA;    static int video_width = 0;&#xA;    static int video_height = 0;&#xA;    static HWND hVideoWnd = nullptr;&#xA;    static HDC hVideoDC = nullptr;&#xA;    static HBITMAP hVideoBitmap = nullptr;&#xA;&#xA;    switch (msg) {&#xA;    case WM_CREATE:&#xA;        break;&#xA;    case WM_SIZE:&#xA;        break;&#xA;    case WM_NOTIFY:&#xA;        //code for handling tab switching &amp; creating all content inside the tabs, currently half-working, perhaps give each tab a show &amp; update win call?&#xA;        if (((LPNMHDR)lParam)->code == TCN_SELCHANGE) {&#xA;            tabIndex = TabCtrl_GetCurSel(g_hWndTabs);&#xA;            if (tabIndex == 0) {&#xA;                DestroyWindow(openFileBtn);&#xA;                DestroyWindow(saveFileBtn);&#xA;                DestroyWindow(emboldenBtn);&#xA;                DestroyWindow(italiciseBtn);&#xA;                DestroyWindow(hEditControl);&#xA;                DestroyWindow(hScrollContainer);&#xA;&#xA;                //this code reloads table data &amp; reconstructs the table whenever the &#x27;table view&#x27; tab is opened,&#xA;                std::wifstream infile("tabledata.txt");&#xA;                while (numRows > 0) {&#xA;                    numRows--;&#xA;                }&#xA;                while (true) {&#xA;                    // Read in data for a row&#xA;                    wchar_t buf1[MAX_PATH], buf2[MAX_PATH], buf3[MAX_PATH];&#xA;                    if (!(infile >> buf1 >> buf2 >> buf3)) {&#xA;                        // End of file reached, break out of loop&#xA;                        break;&#xA;                    }&#xA;&#xA;                    // Create new row window for this row of data&#xA;                    HWND hRow = CreateWindowEx(0, L"STATIC", nullptr,&#xA;                        WS_CHILD | WS_VISIBLE | WS_BORDER,&#xA;                        startX, startY &#x2B; numRows * ROW_HEIGHT,&#xA;                        3 * CELL_WIDTH, ROW_HEIGHT,&#xA;                        g_hWndMain, nullptr, g_hInstance, nullptr);&#xA;&#xA;                    // Create cell edit controls within the new row&#xA;                    HWND hCell1 = CreateWindowEx(0, L"EDIT", nullptr,&#xA;                        WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | WS_BORDER,&#xA;                        0, 0, CELL_WIDTH, ROW_HEIGHT,&#xA;                        hRow, nullptr, g_hInstance, nullptr);&#xA;                    HWND hCell2 = CreateWindowEx(0, L"EDIT", nullptr,&#xA;                        WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | WS_BORDER,&#xA;                        CELL_WIDTH, 0, CELL_WIDTH, ROW_HEIGHT,&#xA;                        hRow, nullptr, g_hInstance, nullptr);&#xA;                    HWND hCell3 = CreateWindowEx(0, L"EDIT", nullptr,&#xA;                        WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | WS_BORDER,&#xA;                        2 * CELL_WIDTH, 0, CELL_WIDTH, ROW_HEIGHT,&#xA;                        hRow, nullptr, g_hInstance, nullptr);&#xA;&#xA;                    // Set the text of each cell edit control&#xA;                    SetWindowTextW(hCell1, buf1);&#xA;                    SetWindowTextW(hCell2, buf2);&#xA;                    SetWindowTextW(hCell3, buf3);&#xA;&#xA;                    // Update the row window&#xA;                    InvalidateRect(hRow, nullptr, TRUE);&#xA;                    UpdateWindow(hRow);&#xA;&#xA;                    numRows&#x2B;&#x2B;;&#xA;                }&#xA;&#xA;&#xA;&#xA;                tblHeaderOne = CreateWindow(L"STATIC", L"Header 1",&#xA;                    WS_CHILD | WS_VISIBLE | SS_CENTER | WS_BORDER,&#xA;                    0, 40, 110, 20,&#xA;                    g_hWndMain, (HMENU)CELL_1_ID, g_hInstance, NULL);&#xA;                InvalidateRect(tblHeaderOne, NULL, TRUE);&#xA;                UpdateWindow(tblHeaderOne);&#xA;&#xA;&#xA;                tblHeaderTwo = CreateWindow(L"STATIC", L"Header 2",&#xA;                    WS_CHILD | WS_VISIBLE | SS_CENTER | WS_BORDER,&#xA;                    110, 40, 110, 20,&#xA;                    g_hWndMain, (HMENU)CELL_2_ID, g_hInstance, NULL);&#xA;                InvalidateRect(tblHeaderTwo, NULL, TRUE);&#xA;                UpdateWindow(tblHeaderTwo);&#xA;&#xA;                tblHeaderThree = CreateWindow(L"STATIC", L"Header 3",&#xA;                    WS_CHILD | WS_VISIBLE | SS_CENTER | WS_BORDER,&#xA;                    220, 40, 110, 20,&#xA;                    g_hWndMain, (HMENU)CELL_3_ID, g_hInstance, NULL);&#xA;                InvalidateRect(tblHeaderThree, NULL, TRUE);&#xA;                UpdateWindow(tblHeaderThree);&#xA;&#xA;                // Create button to add new row&#xA;                addRowBtn = CreateWindow(L"BUTTON", L"Add Row",&#xA;                    WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,&#xA;                    390, 40, 100, 30,&#xA;                    g_hWndMain, (HMENU)ADD_ROW_BTN, g_hInstance, NULL);&#xA;                InvalidateRect(addRowBtn, NULL, TRUE);&#xA;                UpdateWindow(addRowBtn);&#xA;&#xA;            }&#xA;            else if (tabIndex == 1) {&#xA;&#xA;                DestroyWindow(hRow);&#xA;                DestroyWindow(tableContainer);&#xA;                DestroyWindow(tblHeaderOne);&#xA;                DestroyWindow(tblHeaderTwo);&#xA;                DestroyWindow(tblHeaderThree);&#xA;                DestroyWindow(addRowBtn);&#xA;&#xA;&#xA;&#xA;                openFileBtn = CreateWindow(L"BUTTON", L"Open File",&#xA;                    WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,&#xA;                    10, 40, 150, 25,&#xA;                    g_hWndMain, (HMENU)OPEN_FILE_BTN, NULL, NULL);&#xA;                InvalidateRect(openFileBtn, NULL, TRUE);&#xA;                UpdateWindow(openFileBtn);&#xA;&#xA;                saveFileBtn = CreateWindow(L"BUTTON", L"Save File",&#xA;                    WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,&#xA;                    10, 80, 150, 25,&#xA;                    g_hWndMain, (HMENU)SAVE_FILE_BTN, nullptr, nullptr);&#xA;                InvalidateRect(saveFileBtn, NULL, TRUE);&#xA;                UpdateWindow(saveFileBtn);&#xA;&#xA;                hScrollContainer = CreateWindowEx(WS_EX_CLIENTEDGE, L"SCROLLBAR", NULL,&#xA;                    WS_CHILD | WS_VISIBLE | WS_VSCROLL | SBS_VERT,&#xA;                    170, 40, 600, 300,&#xA;                    g_hWndMain, (HMENU)SCROLL_CONTAINER, g_hInstance, NULL);&#xA;&#xA;&#xA;                hEditControl = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", NULL,&#xA;                    WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,&#xA;                    0, 0, 600, 300,&#xA;                    hScrollContainer, (HMENU)EDIT_CONTROL, g_hInstance, NULL);&#xA;                InvalidateRect(hEditControl, NULL, TRUE);&#xA;                UpdateWindow(hEditControl);&#xA;&#xA;                SetFocus(hEditControl);&#xA;&#xA;                SetScrollRange(hScrollContainer, SB_VERT, 0, 5, TRUE);&#xA;                SetScrollPos(hScrollContainer, SB_VERT, 0, TRUE);&#xA;&#xA;                // Add embolden button&#xA;                emboldenBtn = CreateWindow(L"BUTTON", L"Embolden",&#xA;                    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,&#xA;                    10, 120, 100, 25,&#xA;                    g_hWndMain, (HMENU)EMBOLDEN_BTN, nullptr, nullptr);&#xA;                InvalidateRect(emboldenBtn, NULL, TRUE);&#xA;                UpdateWindow(emboldenBtn);&#xA;&#xA;                // Add italicise button&#xA;                italiciseBtn = CreateWindow(L"BUTTON", L"Italicise",&#xA;                    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,&#xA;                    10, 150, 100, 25,&#xA;                    g_hWndMain, (HMENU)ITALICISE_BTN, nullptr, nullptr);&#xA;                InvalidateRect(italiciseBtn, NULL, TRUE);&#xA;                UpdateWindow(italiciseBtn);&#xA;            }&#xA;            else if (tabIndex == 2) {&#xA;                DestroyWindow(hRow);&#xA;                DestroyWindow(tableContainer);&#xA;                DestroyWindow(tblHeaderOne);&#xA;                DestroyWindow(tblHeaderTwo);&#xA;                DestroyWindow(tblHeaderThree);&#xA;                DestroyWindow(addRowBtn);&#xA;                DestroyWindow(openFileBtn);&#xA;                DestroyWindow(saveFileBtn);&#xA;                DestroyWindow(emboldenBtn);&#xA;                DestroyWindow(italiciseBtn);&#xA;                DestroyWindow(hEditControl);&#xA;                DestroyWindow(hScrollContainer);&#xA;&#xA;                // Create container for player&#xA;                hWMPContainer = CreateWindowEx(WS_EX_CLIENTEDGE, L"STATIC", nullptr,&#xA;                    WS_CHILD | WS_VISIBLE | SS_CENTER | SS_GRAYFRAME,&#xA;                    50, 50, 700, 400,&#xA;                    g_hWndMain, nullptr, g_hInstance, nullptr);&#xA;&#xA;                // Create Open .mp4/.mov button&#xA;                OpenMp4Btn = CreateWindow(L"BUTTON", L"Open .mp4/.mov",&#xA;                    WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,&#xA;                    50, 460, 150, 30,&#xA;                    g_hWndMain, (HMENU)FILEMENU_OPEN_FILE_BTN, nullptr, nullptr);&#xA;                InvalidateRect(OpenMp4Btn, nullptr, TRUE);&#xA;                UpdateWindow(OpenMp4Btn);&#xA;&#xA;&#xA;                // Create play/pause button&#xA;                hPlayBtn = CreateWindow(L"BUTTON", L"Play",&#xA;                    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,&#xA;                    350, 460, 100, 30,&#xA;                    g_hWndMain, nullptr, g_hInstance, nullptr);&#xA;                InvalidateRect(hPlayBtn, nullptr, TRUE);&#xA;                UpdateWindow(hPlayBtn);&#xA;&#xA;            }&#xA;        }&#xA;        return DefWindowProc(hwnd, msg, wParam, lParam);&#xA;        break;&#xA;    case WM_MOUSEWHEEL:&#xA;        //also WIP, will be developed after WM_VSCROLL is established&#xA;        break;&#xA;    case WM_VSCROLL:&#xA;        //to be developed 9516555&#xA;    case WM_PAINT:&#xA;        break;&#xA;    case WM_COMMAND:&#xA;        //all commands passed to the window through buttons, menus, forms, etc.&#xA;        if (HIWORD(wParam) == BN_CLICKED) {&#xA;            if ((HWND)lParam == addRowBtn) {&#xA;                const wchar_t* ROW_CLASS_NAME = L"Row Window";&#xA;                WNDCLASS rowWc{};&#xA;                rowWc.hInstance = g_hInstance;&#xA;                rowWc.lpszClassName = ROW_CLASS_NAME;&#xA;                rowWc.hCursor = LoadCursor(nullptr, IDC_ARROW);&#xA;                rowWc.hbrBackground = (HBRUSH)COLOR_WINDOW;&#xA;                rowWc.lpfnWndProc = AddRowDlgProc;&#xA;                RegisterClass(&amp;rowWc);&#xA;&#xA;                hWnd = CreateWindow(ROW_CLASS_NAME, L"Row Window",&#xA;                    WS_OVERLAPPEDWINDOW,&#xA;                    CW_USEDEFAULT, CW_USEDEFAULT,&#xA;                    250, 200,&#xA;                    nullptr, nullptr, nullptr, nullptr);&#xA;&#xA;                // Create text box controls&#xA;                hWndCell1Label = CreateWindowW(&#xA;                    L"STATIC", L"Cell 1:",&#xA;                    WS_CHILD | WS_VISIBLE | SS_LEFT,&#xA;                    10, 10, 50, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;&#xA;                hWndCell1Edit = CreateWindowW(&#xA;                    L"EDIT", NULL,&#xA;                    WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL,&#xA;                    65, 10, 100, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;&#xA;                hWndCell2Label = CreateWindowW(&#xA;                    L"STATIC", L"Cell 2:",&#xA;                    WS_CHILD | WS_VISIBLE | SS_LEFT,&#xA;                    10, 40, 50, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;&#xA;                hWndCell2Edit = CreateWindowW(&#xA;                    L"EDIT", NULL,&#xA;                    WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL,&#xA;                    65, 40, 100, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;                hWndCell3Label = CreateWindowW(&#xA;                    L"STATIC", L"Cell 3:",&#xA;                    WS_CHILD | WS_VISIBLE | SS_LEFT,&#xA;                    10, 70, 50, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;&#xA;                hWndCell3Edit = CreateWindowW(&#xA;                    L"EDIT", NULL,&#xA;                    WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL,&#xA;                    65, 70, 100, 20,&#xA;                    hWnd, NULL, g_hInstance, NULL);&#xA;&#xA;&#xA;                // Create OK and Cancel button controls&#xA;                hWndOkButton = CreateWindowW(&#xA;                    L"BUTTON", L"OK",&#xA;                    WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,&#xA;                    40, 110, 50, 25,&#xA;                    hWnd, (HMENU)IDOK, g_hInstance, NULL);&#xA;&#xA;&#xA;                hWndCancelButton = CreateWindowW(&#xA;                    L"BUTTON", L"Cancel",&#xA;                    WS_CHILD | WS_VISIBLE,&#xA;                    100, 110, 50, 25,&#xA;                    hWnd, (HMENU)IDCANCEL, g_hInstance, NULL);&#xA;&#xA;&#xA;                ShowWindow(hWnd, SW_SHOW);&#xA;                UpdateWindow(hWnd);&#xA;&#xA;                MSG msg{};&#xA;                while (GetMessage(&amp;msg, nullptr, 0, 0)) {&#xA;                    TranslateMessage(&amp;msg);&#xA;                    DispatchMessage(&amp;msg);&#xA;                }&#xA;&#xA;            }&#xA;            if ((HWND)lParam == openFileBtn) {&#xA;                // Open File button clicked, show open file dialoge and load the selected file into the edit control&#xA;                OPENFILENAME ofn = { };&#xA;                WCHAR szFile[MAX_PATH] = L"";&#xA;                ofn.lStructSize = sizeof(OPENFILENAME);&#xA;                ofn.hwndOwner = hWnd;&#xA;                ofn.lpstrFilter = L"Text files\0*.txt\0All files\0*.*\0";&#xA;                ofn.lpstrFile = szFile;&#xA;                ofn.nMaxFile = MAX_PATH;&#xA;                ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;&#xA;                if (GetOpenFileName(&amp;ofn)) {&#xA;                    // Read file and set text of edit box&#xA;                    std::ifstream infile(ofn.lpstrFile, std::ios::in | std::ios::binary);&#xA;                    if (infile) {&#xA;                        std::wstring text((std::istreambuf_iterator<char>(infile)), std::istreambuf_iterator<char>());&#xA;                        SetWindowText(hEditControl, text.c_str());&#xA;                        filePath = ofn.lpstrFile;&#xA;                    }&#xA;                }&#xA;            }&#xA;            if ((HWND)lParam == saveFileBtn) {&#xA;                if (!filePath.empty()) {&#xA;                    std::wofstream outfile(filePath, std::ios::out | std::ios::binary); // use std::wofstream instead of std::ofstream&#xA;                    if (outfile) {&#xA;                        int textLength = GetWindowTextLength(hEditControl);&#xA;                        if (textLength != 0) {&#xA;                            wchar_t* textBuffer = new wchar_t[textLength &#x2B; 1];&#xA;                            GetWindowTextW(hEditControl, textBuffer, textLength &#x2B; 1);&#xA;                            outfile.write(textBuffer, textLength * sizeof(wchar_t));&#xA;                            delete[] textBuffer;&#xA;                        }&#xA;                    }&#xA;                    outfile.close();&#xA;                    MessageBox(NULL, L"File saved successfully!", L"File save", MB_OK);&#xA;                }&#xA;&#xA;            }&#xA;            //The following are not currently working due to an issue in connecting to the edit box for char type manipulation&#xA;            if ((HWND)lParam == emboldenBtn) {&#xA;&#xA;            }&#xA;            if ((HWND)lParam == italiciseBtn) {&#xA;&#xA;            }&#xA;            //cannot or failed to open video file &#xA;            if ((HWND)lParam == OpenMp4Btn) {&#xA;                OPENFILENAMEA ofn = {};&#xA;                ofn.lStructSize = sizeof(ofn);&#xA;                ofn.hwndOwner = hwnd;&#xA;                ofn.lpstrFilter = "Video Files (*.mp4;*.mov)\0*.mp4;*.mov\0All Files (*.*)\0*.*\0";&#xA;                char szFile[MAX_PATH] = {};&#xA;                ofn.lpstrFile = szFile;&#xA;                ofn.nMaxFile = MAX_PATH;&#xA;                ofn.lpstrTitle = "Open Video File";&#xA;                ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;&#xA;                if (GetOpenFileNameA(&amp;ofn)) {&#xA;                    // Initialize SDL&#xA;                    SDL_Init(SDL_INIT_VIDEO);&#xA;&#xA;                    // Open the selected video file&#xA;                    AVFormatContext* format_ctx = nullptr;&#xA;                    if (avformat_open_input(&amp;format_ctx, szFile, nullptr, nullptr) != 0) {&#xA;                        // Error handling&#xA;                    }&#xA;&#xA;                    // Retrieve stream information&#xA;                    if (avformat_find_stream_info(format_ctx, nullptr) &lt; 0) {&#xA;                        // Error handling&#xA;                    }&#xA;&#xA;                    // Find the video and audio streams&#xA;                    int video_stream_idx = av_find_best_stream(format_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);&#xA;                    int audio_stream_idx = av_find_best_stream(format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);&#xA;&#xA;                    // Open the video and audio codecs&#xA;                    AVCodecContext* video_codec_ctx = avcodec_alloc_context3(nullptr);&#xA;                    avcodec_parameters_to_context(video_codec_ctx, format_ctx->streams[video_stream_idx]->codecpar);&#xA;                    AVCodec* video_codec = const_cast(avcodec_find_decoder(video_codec_ctx->codec_id));&#xA;                    if (avcodec_open2(video_codec_ctx, video_codec, nullptr) &lt; 0) {&#xA;                        // Error handling&#xA;                    }&#xA;&#xA;                    AVCodecContext* audio_codec_ctx = avcodec_alloc_context3(nullptr);&#xA;                    avcodec_parameters_to_context(audio_codec_ctx, format_ctx->streams[audio_stream_idx]->codecpar);&#xA;                    AVCodec* audio_codec = const_cast(avcodec_find_decoder(audio_codec_ctx->codec_id));&#xA;                    if (avcodec_open2(audio_codec_ctx, audio_codec, nullptr) &lt; 0) {&#xA;                        // Error handling&#xA;                    }&#xA;                    // Allocate memory for the video and audio frames&#xA;                    AVFrame* video_frame = av_frame_alloc();&#xA;                    AVFrame* audio_frame = av_frame_alloc();&#xA;&#xA;                    // Create a window for displaying the video frames&#xA;                    SDL_Window* window = SDL_CreateWindow("Video Player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, video_codec_ctx->width, video_codec_ctx->height, SDL_WINDOW_SHOWN);&#xA;&#xA;                    // Create a renderer for displaying the video frames&#xA;                    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);&#xA;&#xA;                    // Create a texture for displaying the video frames&#xA;                    SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_BGR24, SDL_TEXTUREACCESS_STREAMING, video_codec_ctx->width, video_codec_ctx->height);&#xA;&#xA;                    // Create a scaling context for converting the video frames to RGB&#xA;                    SwsContext* sws_ctx = sws_getContext(video_codec_ctx->width, video_codec_ctx->height, video_codec_ctx->pix_fmt,&#xA;                        video_codec_ctx->width, video_codec_ctx->height, AV_PIX_FMT_BGR24,&#xA;                        SWS_BILINEAR, nullptr, nullptr, nullptr);&#xA;&#xA;                    // Decode and display the video frames&#xA;                    AVPacket packet;&#xA;                    while (av_read_frame(format_ctx, &amp;packet) >= 0) {&#xA;                        if (packet.stream_index == video_stream_idx) {&#xA;                            avcodec_send_packet(video_codec_ctx, &amp;packet);&#xA;                            while (avcodec_receive_frame(video_codec_ctx, video_frame) == 0) {&#xA;                                sws_scale(sws_ctx, video_frame->data, video_frame->linesize, 0, video_codec_ctx->height,&#xA;                                    video_frame->data, video_frame->linesize);&#xA;                                SDL_UpdateTexture(texture, NULL, video_frame->data[0], video_frame->linesize[0]);&#xA;                                SDL_RenderClear(renderer);&#xA;                                SDL_RenderCopy(renderer, texture, NULL, NULL);&#xA;                                SDL_RenderPresent(renderer);&#xA;                            }&#xA;                        }&#xA;                        av_packet_unref(&amp;packet);&#xA;                    }&#xA;&#xA;                    // Free the allocated memory and close the codecs&#xA;                    av_frame_free(&amp;video_frame);&#xA;                    av_frame_free(&amp;audio_frame);&#xA;                    avcodec_free_context(&amp;video_codec_ctx);&#xA;                    avcodec_free_context(&amp;audio_codec_ctx);&#xA;                    avformat_close_input(&amp;format_ctx);&#xA;&#xA;                    // Destroy the window, renderer, and texture&#xA;                    SDL_DestroyTexture(texture);&#xA;                    SDL_DestroyRenderer(renderer);&#xA;                    SDL_DestroyWindow(window);&#xA;&#xA;                    // Quit SDL&#xA;                    SDL_Quit();&#xA;                }&#xA;            }&#xA;        }&#xA;        break;&#xA;    case WM_DESTROY:&#xA;        //code that executes on window destruction&#xA;        PostQuitMessage(0);&#xA;        return 0;&#xA;    default:&#xA;        return DefWindowProc(hwnd, msg, wParam, lParam);&#xA;    }&#xA;}&#xA;</char></char>

    &#xA;

    I am doing this on MVSC2022 in a C++ win32 application if it's relevant, I will attach some images of the video : some of the videosome more of the videoA screenshot of the output screen

    &#xA;